From 8afe6f260b19f148398784a2a918006b91bb4096 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 11 Oct 2011 08:56:00 +0000 Subject: [PATCH] process inbound type map messages: --- src/core/gnunet-service-core_clients.c | 7 +- src/core/gnunet-service-core_clients.h | 4 +- src/core/gnunet-service-core_kx.c | 29 ++++++--- src/core/gnunet-service-core_sessions.c | 67 ++++++++++++++++++- src/core/gnunet-service-core_sessions.h | 24 +++++++ src/core/gnunet-service-core_typemap.c | 86 ++++++++++++++++++++++++- src/core/gnunet-service-core_typemap.h | 33 ++++++++++ 7 files changed, 232 insertions(+), 18 deletions(-) diff --git a/src/core/gnunet-service-core_clients.c b/src/core/gnunet-service-core_clients.c index 0b1616c97..9b442bf30 100644 --- a/src/core/gnunet-service-core_clients.c +++ b/src/core/gnunet-service-core_clients.c @@ -578,7 +578,7 @@ GSC_CLIENTS_reject_request (struct GSC_ClientActiveRequest *car) * @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, @@ -651,7 +651,7 @@ GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client, * @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, @@ -660,7 +660,7 @@ GDS_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *ne 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); } @@ -713,6 +713,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, 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); diff --git a/src/core/gnunet-service-core_clients.h b/src/core/gnunet-service-core_clients.h index 7e316d90f..9774292c0 100644 --- a/src/core/gnunet-service-core_clients.h +++ b/src/core/gnunet-service-core_clients.h @@ -58,7 +58,7 @@ GSC_CLIENTS_send_to_client (struct GNUNET_SERVER_Client *client, * @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, @@ -78,7 +78,7 @@ GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client, * @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, diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index 8daf49826..19b692ab9 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c @@ -1418,16 +1418,25 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m) { 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); + } } diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 7b159022c..480857642 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c @@ -188,6 +188,11 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) 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); } @@ -247,7 +252,7 @@ notify_client_about_session (void *cls, 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 */ @@ -689,6 +694,66 @@ GSC_SESSIONS_handle_client_have_peer (void *cls, struct GNUNET_SERVER_Client *cl } +/** + * 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. */ diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h index a795c417c..b70bd59fd 100644 --- a/src/core/gnunet-service-core_sessions.h +++ b/src/core/gnunet-service-core_sessions.h @@ -116,6 +116,30 @@ GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg); 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 diff --git a/src/core/gnunet-service-core_typemap.c b/src/core/gnunet-service-core_typemap.c index 78dfc2bb9..db9b2a136 100644 --- a/src/core/gnunet-service-core_typemap.c +++ b/src/core/gnunet-service-core_typemap.c @@ -72,7 +72,6 @@ GSC_TYPEMAP_compute_type_map_message () * 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, @@ -86,10 +85,56 @@ GSC_TYPEMAP_compute_type_map_message () { 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). */ @@ -169,12 +214,49 @@ GSC_TYPEMAP_test_match (const struct GSC_TypeMap *tmap, unsigned int i; for (i=0;ibits[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;ibits[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. */ diff --git a/src/core/gnunet-service-core_typemap.h b/src/core/gnunet-service-core_typemap.h index 10c614a85..72eb5b566 100644 --- a/src/core/gnunet-service-core_typemap.h +++ b/src/core/gnunet-service-core_typemap.h @@ -60,6 +60,16 @@ struct GNUNET_MessageHeader * 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. @@ -75,6 +85,29 @@ GSC_TYPEMAP_test_match (const struct GSC_TypeMap *tmap, 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. */ -- 2.25.1