* @param tmap_new updated type map for the neighbour, NULL for disconnect
*/
void
-GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
+GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
const struct GNUNET_PeerIdentity *neighbour,
const struct GNUNET_TRANSPORT_ATS_Information *atsi,
unsigned int atsi_count,
* @param tmap_new updated type map for the neighbour, NULL for disconnect
*/
void
-GDS_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
+GSC_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
const struct GNUNET_TRANSPORT_ATS_Information *atsi,
unsigned int atsi_count,
const struct GSC_TypeMap *tmap_old,
struct GSC_Client *c;
for (c = client_head; c != NULL; c = c->next)
- GDS_CLIENTS_notify_client_about_neighbour (c, neighbour, atsi,
+ GSC_CLIENTS_notify_client_about_neighbour (c, neighbour, atsi,
atsi_count,
tmap_old, tmap_new);
}
GNUNET_i2s (sender),
(unsigned int) ntohs (msg->type));
#endif
+ GSC_SESSIONS_add_to_typemap (sender, ntohs (msg->type));
ntm = (struct NotifyTrafficMessage *) buf;
ntm->header.size = htons (size);
ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
* @param tmap_new updated type map for the neighbour, NULL for disconnect
*/
void
-GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
+GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
const struct GNUNET_PeerIdentity *neighbour,
const struct GNUNET_TRANSPORT_ATS_Information *atsi,
unsigned int atsi_count,
* @param tmap_new updated type map for the neighbour, NULL for disconnect
*/
void
-GDS_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
+GSC_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
const struct GNUNET_TRANSPORT_ATS_Information *atsi,
unsigned int atsi_count,
const struct GSC_TypeMap *tmap_old,
{
struct DeliverMessageContext *dmc = client;
- 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 (dmc->peer,
- dmc->atsi, dmc->atsi_count,
- m,
- sizeof (struct GNUNET_MessageHeader),
- GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
+ switch (ntohs (m->type))
+ {
+ case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
+ case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
+ GSC_SESSIONS_set_typemap (dmc->peer,
+ m);
+ return;
+ default:
+ 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 (dmc->peer,
+ dmc->atsi, dmc->atsi_count,
+ m,
+ sizeof (struct GNUNET_MessageHeader),
+ GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
+ }
}
gettext_noop ("# established sessions"),
GNUNET_CONTAINER_multihashmap_size (sessions),
GNUNET_NO);
+ if (NULL != session->tmap)
+ {
+ GSC_TYPEMAP_destroy (session->tmap);
+ session->tmap = NULL;
+ }
GNUNET_free (session);
}
struct GSC_Client *client = cls;
struct Session *session = value;
- GDS_CLIENTS_notify_client_about_neighbour (client,
+ GSC_CLIENTS_notify_client_about_neighbour (client,
&session->peer,
NULL, 0, /* FIXME: ATS!? */
NULL, /* old TMAP: none */
}
+/**
+ * We've received a typemap message from a peer, update ours.
+ * Notifies clients about the session.
+ *
+ * @param peer peer this is about
+ * @param msg typemap update message
+ */
+void
+GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *msg)
+{
+ struct Session *session;
+ struct GSC_TypeMap *nmap;
+
+ nmap = GSC_TYPEMAP_get_from_message (msg);
+ if (NULL == nmap)
+ return; /* malformed */
+ session = find_session (peer);
+ GSC_CLIENTS_notify_clients_about_neighbour (peer,
+ NULL, 0, /* FIXME: ATS */
+ session->tmap,
+ nmap);
+ if (NULL != session->tmap)
+ GSC_TYPEMAP_destroy (session->tmap);
+ session->tmap = nmap;
+}
+
+
+/**
+ * The given peer send a message of the specified type. Make sure the
+ * respective bit is set in its type-map and that clients are notified
+ * about the session.
+ *
+ * @param peer peer this is about
+ * @param type type of the message
+ */
+void
+GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer,
+ uint16_t type)
+{
+ struct Session *session;
+ struct GSC_TypeMap *nmap;
+
+ session = find_session (peer);
+ if (GNUNET_YES ==
+ GSC_TYPEMAP_test_match (session->tmap,
+ &type, 1))
+ return; /* already in it */
+ nmap = GSC_TYPEMAP_extend (session->tmap,
+ &type, 1);
+ GSC_CLIENTS_notify_clients_about_neighbour (peer,
+ NULL, 0, /* FIXME: ATS */
+ session->tmap,
+ nmap);
+ if (NULL != session->tmap)
+ GSC_TYPEMAP_destroy (session->tmap);
+ session->tmap = nmap;
+}
+
+
/**
* Initialize sessions subsystem.
*/
void
GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client);
+/**
+ * We've received a typemap message from a peer, update ours.
+ * Notifies clients about the session.
+ *
+ * @param peer peer this is about
+ * @param msg typemap update message
+ */
+void
+GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *msg);
+
+
+/**
+ * The given peer send a message of the specified type. Make sure the
+ * respective bit is set in its type-map and that clients are notified
+ * about the session.
+ *
+ * @param peer peer this is about
+ * @param type type of the message
+ */
+void
+GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer,
+ uint16_t type);
+
/**
* Handle CORE_ITERATE_PEERS request. For this request type, the client
* should be able to overshoot by more to be safe */
#endif
hdr = GNUNET_malloc (dlen + sizeof (struct GNUNET_MessageHeader));
- hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
tmp = (char *) &hdr[1];
if ((Z_OK !=
compress2 ((Bytef *) tmp, &dlen, (const Bytef *) &my_type_map,
{
hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP);
}
+ hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
return hdr;
}
+/**
+ * Extract a type map from a TYPE_MAP message.
+ *
+ * @param msg a type map message
+ * @return NULL on error
+ */
+struct GSC_TypeMap *
+GSC_TYPEMAP_get_from_message (const struct GNUNET_MessageHeader *msg)
+{
+ struct GSC_TypeMap *ret;
+ uint16_t size;
+ uLongf dlen;
+
+ size = ntohs (msg->size);
+ switch (msg->type)
+ {
+ case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
+ if (size != sizeof (struct GSC_TypeMap))
+ {
+ GNUNET_break_op (0);
+ return NULL;
+ }
+ ret = GNUNET_malloc (sizeof (struct GSC_TypeMap));
+ memcpy (ret, &msg[1], sizeof (struct GSC_TypeMap));
+ return ret;
+ case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
+ ret = GNUNET_malloc (sizeof (struct GSC_TypeMap));
+ dlen = sizeof (struct GSC_TypeMap);
+ if ( (Z_OK !=
+ uncompress ((Bytef*) ret, &dlen,
+ (const Bytef*) &msg[1], (uLong) size)) ||
+ (dlen != sizeof (struct GSC_TypeMap) ) )
+ {
+ GNUNET_break_op (0);
+ GNUNET_free (ret);
+ return NULL;
+ }
+ return ret;
+ default:
+ GNUNET_break (0);
+ return NULL;
+ }
+}
+
+
/**
* Send my type map to all connected peers (it got changed).
*/
unsigned int i;
for (i=0;i<tcnt;i++)
- if (0 != (my_type_map.bits[types[i] / 32] & (1 << (types[i] % 32))))
+ if (0 != (tmap->bits[types[i] / 32] & (1 << (types[i] % 32))))
return GNUNET_YES;
return GNUNET_NO;
}
+/**
+ * Add additional types to a given typemap.
+ *
+ * @param map map to extend (not changed)
+ * @param types array of types to add
+ * @param tcnt number of entries in types
+ * @return updated type map (fresh copy)
+ */
+struct GSC_TypeMap *
+GSC_TYPEMAP_extend (const struct GSC_TypeMap *tmap,
+ const uint16_t *types,
+ unsigned int tcnt)
+{
+ struct GSC_TypeMap *ret;
+ unsigned int i;
+
+ ret = GNUNET_malloc (sizeof (struct GSC_TypeMap));
+ if (NULL != tmap)
+ memcpy (ret, tmap, sizeof (struct GSC_TypeMap));
+ for (i=0;i<tcnt;i++)
+ ret->bits[types[i] / 32] |= (1 << (types[i] % 32));
+ return ret;
+}
+
+
+/**
+ * Free the given type map.
+ *
+ * @param map a type map
+ */
+void
+GSC_TYPEMAP_destroy (struct GSC_TypeMap *tmap)
+{
+ GNUNET_free (tmap);
+}
+
+
/**
* Initialize typemap subsystem.
*/
GSC_TYPEMAP_compute_type_map_message (void);
+/**
+ * Extract a type map from a TYPE_MAP message.
+ *
+ * @param msg a type map message
+ * @return NULL on error
+ */
+struct GSC_TypeMap *
+GSC_TYPEMAP_get_from_message (const struct GNUNET_MessageHeader *msg);
+
+
/**
* Test if any of the types from the types array is in the
* given type map.
unsigned int tcnt);
+/**
+ * Add additional types to a given typemap.
+ *
+ * @param map map to extend (not changed)
+ * @param types array of types to add
+ * @param tcnt number of entries in types
+ * @return updated type map (fresh copy)
+ */
+struct GSC_TypeMap *
+GSC_TYPEMAP_extend (const struct GSC_TypeMap *tmap,
+ const uint16_t *types,
+ unsigned int tcnt);
+
+
+/**
+ * Free the given type map.
+ *
+ * @param map a type map
+ */
+void
+GSC_TYPEMAP_destroy (struct GSC_TypeMap *tmap);
+
+
/**
* Initialize typemap subsystem.
*/