X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fcore%2Fgnunet-service-core_clients.c;h=3201b71f0e0c3b9659d16e42bc29755391974f56;hb=83b19539f4d322b43683f5838b72e9ec2c8e6073;hp=00d22c13fa48429b147cefa9ad459e6d2fbbbb79;hpb=648a6cd5055798507a011b1e9c0d612371ce7a8d;p=oweals%2Fgnunet.git diff --git a/src/core/gnunet-service-core_clients.c b/src/core/gnunet-service-core_clients.c index 00d22c13f..3201b71f0 100644 --- a/src/core/gnunet-service-core_clients.c +++ b/src/core/gnunet-service-core_clients.c @@ -33,6 +33,8 @@ #include "gnunet-service-core_typemap.h" #include "core.h" +#define DEBUG_CONNECTS GNUNET_YES + /** * How many messages do we queue up at most for optional * notifications to a client? (this can cause notifications @@ -74,6 +76,13 @@ struct GSC_Client */ struct GNUNET_CONTAINER_MultiHashMap *requests; +#if DEBUG_CONNECTS + /** + * Map containing all peers that this client knows we're connected to. + */ + struct GNUNET_CONTAINER_MultiHashMap *connectmap; +#endif + /** * Options for messages this client cares about, * see GNUNET_CORE_OPTION_ values. @@ -137,11 +146,10 @@ find_client (struct GNUNET_SERVER_Client *client) * client's queue is getting too large? */ static void -send_to_client (struct GSC_Client *client, - const struct GNUNET_MessageHeader *msg, - int can_drop) +send_to_client (struct GSC_Client *client, + const struct GNUNET_MessageHeader *msg, int can_drop) { -#if DEBUG_CORE_CLIENT +#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Preparing to send %u bytes of message of type %u to client.\n", (unsigned int) ntohs (msg->size), @@ -162,8 +170,8 @@ send_to_client (struct GSC_Client *client, */ void GSC_CLIENTS_send_to_client (struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *msg, - int can_drop) + const struct GNUNET_MessageHeader *msg, + int can_drop) { struct GSC_Client *c; @@ -185,12 +193,13 @@ GSC_CLIENTS_send_to_client (struct GNUNET_SERVER_Client *client, * @return GNUNET_YES if 'c' is interested, GNUNET_NO if not. */ static int -type_match (uint16_t type, - struct GSC_Client *c) +type_match (uint16_t type, struct GSC_Client *c) { unsigned int i; - for (i=0;itcnt;i++) + if (c->tcnt == 0) + return GNUNET_YES; /* peer without handlers matches ALL */ + for (i = 0; i < c->tcnt; i++) if (type == c->types[i]) return GNUNET_YES; return GNUNET_NO; @@ -207,23 +216,28 @@ type_match (uint16_t type, * @param type type of the embedded message, 0 for none */ static void -send_to_all_clients (const struct GNUNET_MessageHeader *msg, - int can_drop, - int options, - uint16_t type) +send_to_all_clients (const struct GNUNET_PeerIdentity *sender, + const struct GNUNET_MessageHeader *msg, int can_drop, + int options, uint16_t type) { struct GSC_Client *c; for (c = client_head; c != NULL; c = c->next) { - if (! ( (0 != (c->options & options)) || - ( (0 != (options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) && - (GNUNET_YES == type_match (type, c)) ) ) ) - continue; /* skip */ -#if DEBUG_CORE_CLIENT > 1 + if ((0 == (options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) && + (GNUNET_YES == type_match (type, c))) + continue; /* not the full message, but we'd like the full one! */ + if ((0 == (c->options & options)) && (GNUNET_YES != type_match (type, c))) + continue; /* neither options nor type match permit the message */ +#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending message of type %u to client.\n", - (unsigned int) ntohs (msg->type)); + "Sending message to client interested in messages of type %u.\n", + (unsigned int) type); +#endif +#if DEBUG_CONNECTS + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_contains (c->connectmap, + &sender->hashPubKey)); #endif send_to_client (c, msg, can_drop); } @@ -273,16 +287,23 @@ handle_client_init (void *cls, struct GNUNET_SERVER_Client *client, c->tcnt = msize / sizeof (uint16_t); c->options = ntohl (im->options); c->types = (const uint16_t *) &c[1]; +#if DEBUG_CONNECTS + c->connectmap = GNUNET_CONTAINER_multihashmap_create (16); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_put (c->connectmap, + &GSC_my_identity.hashPubKey, + NULL, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); +#endif + wtypes = (uint16_t *) & c[1]; for (i = 0; i < c->tcnt; i++) wtypes[i] = ntohs (types[i]); GSC_TYPEMAP_add (wtypes, c->tcnt); - GNUNET_CONTAINER_DLL_insert (client_head, - client_tail, - c); -#if DEBUG_CORE_CLIENT + GNUNET_CONTAINER_DLL_insert (client_head, client_tail, c); +#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client connecting to core service is interested in %u message types\n", + "Client connecting to core service is interested in %u message types\n", (unsigned int) c->tcnt); #endif /* send init reply message */ @@ -291,8 +312,7 @@ handle_client_init (void *cls, struct GNUNET_SERVER_Client *client, irm.reserved = htonl (0); irm.my_identity = GSC_my_identity; send_to_client (c, &irm.header, GNUNET_NO); - if (0 != (c->options & GNUNET_CORE_OPTION_SEND_CONNECT)) - GSC_SESSIONS_notify_client_about_sessions (c); + GSC_SESSIONS_notify_client_about_sessions (c); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -302,7 +322,7 @@ handle_client_init (void *cls, struct GNUNET_SERVER_Client *client, * * @param cls unused * @param client new client that sent CORE_SEND_REQUEST - * @param message the 'struct InitMessage' (presumably) + * @param message the 'struct SendMessageRequest' (presumably) */ static void handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client, @@ -323,6 +343,11 @@ handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client, } if (c->requests == NULL) c->requests = GNUNET_CONTAINER_multihashmap_create (16); +#if DEBUG_CORE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client asked for transmission to `%s'\n", + GNUNET_i2s (&req->peer)); +#endif car = GNUNET_CONTAINER_multihashmap_get (c->requests, &req->peer.hashPubKey); if (car == NULL) { @@ -335,6 +360,10 @@ handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); car->client_handle = c; } + else + { + GSC_SESSIONS_dequeue_request (car); + } car->target = req->peer; car->deadline = GNUNET_TIME_absolute_ntoh (req->deadline); car->priority = ntohl (req->priority); @@ -342,7 +371,8 @@ handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client, car->smr_id = req->smr_id; car->was_solicited = GNUNET_NO; if (0 == - memcmp (&req->peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) + memcmp (&req->peer, &GSC_my_identity, + sizeof (struct GNUNET_PeerIdentity))) GSC_CLIENTS_solicit_request (car); else GSC_SESSIONS_queue_request (car); @@ -350,6 +380,25 @@ handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client, } +/** + * Closure for the 'client_tokenizer_callback'. + */ +struct TokenizerContext +{ + + /** + * Active request handle for the message. + */ + struct GSC_ClientActiveRequest *car; + + /** + * Is corking allowed (set only once we have the real message). + */ + int cork; + +}; + + /** * Handle CORE_SEND request. * @@ -363,7 +412,7 @@ handle_client_send (void *cls, struct GNUNET_SERVER_Client *client, { const struct SendMessage *sm; struct GSC_Client *c; - struct GSC_ClientActiveRequest *car; + struct TokenizerContext tc; uint16_t msize; msize = ntohs (message->size); @@ -385,28 +434,39 @@ handle_client_send (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - car = GNUNET_CONTAINER_multihashmap_get (c->requests, &sm->peer.hashPubKey); - if (NULL == car) + tc.car = + GNUNET_CONTAINER_multihashmap_get (c->requests, &sm->peer.hashPubKey); + if (NULL == tc.car) { - /* client did not request transmission first! */ - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + /* Must have been that we first approved the request, then got disconnected + * (which triggered removal of the 'car') and now the client gives us a message + * just *before* the client learns about the disconnect. Theoretically, we + * might also now be *again* connected. So this can happen (but should be + * rare). If it does happen, the message is discarded. */ + GNUNET_STATISTICS_update (GSC_stats, + gettext_noop + ("# messages discarded (session disconnected)"), + 1, GNUNET_NO); + GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (c->requests, - &sm->peer.hashPubKey, - car)); - car->cork = ntohs (sm->cork); - GNUNET_SERVER_mst_receive (client_mst, - car, - (const char*) &sm[1], msize, - GNUNET_YES, - GNUNET_NO); + GNUNET_CONTAINER_multihashmap_remove (c->requests, + &sm->peer.hashPubKey, + tc.car)); + tc.cork = ntohl (sm->cork); +#if DEBUG_CORE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client asked for transmission of %u bytes to `%s' %s\n", msize, + GNUNET_i2s (&sm->peer), tc.cork ? "now" : ""); +#endif + GNUNET_SERVER_mst_receive (client_mst, &tc, (const char *) &sm[1], msize, + GNUNET_YES, GNUNET_NO); if (0 != - memcmp (&car->target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) - GSC_SESSIONS_dequeue_request (car); - GNUNET_free (car); + memcmp (&tc.car->target, &GSC_my_identity, + sizeof (struct GNUNET_PeerIdentity))) + GSC_SESSIONS_dequeue_request (tc.car); + GNUNET_free (tc.car); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -423,26 +483,38 @@ handle_client_send (void *cls, struct GNUNET_SERVER_Client *client, */ static void client_tokenizer_callback (void *cls, void *client, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_MessageHeader *message) { - struct GSC_ClientActiveRequest *car = client; + struct TokenizerContext *tc = client; + struct GSC_ClientActiveRequest *car = tc->car; if (0 == - memcmp (&car->target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) + memcmp (&car->target, &GSC_my_identity, + sizeof (struct GNUNET_PeerIdentity))) { - GSC_CLIENTS_deliver_message (&GSC_my_identity, - NULL, 0, - message, - ntohs (message->size), - GNUNET_CORE_OPTION_SEND_FULL_INBOUND | GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND); - GSC_CLIENTS_deliver_message (&GSC_my_identity, - NULL, 0, - message, - sizeof (struct GNUNET_MessageHeader), - GNUNET_CORE_OPTION_SEND_HDR_INBOUND | GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND); +#if DEBUG_CORE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Delivering message of type %u to myself\n", + ntohs (message->type)); +#endif + GSC_CLIENTS_deliver_message (&GSC_my_identity, NULL, 0, message, + ntohs (message->size), + GNUNET_CORE_OPTION_SEND_FULL_INBOUND | + GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND); + GSC_CLIENTS_deliver_message (&GSC_my_identity, NULL, 0, message, + sizeof (struct GNUNET_MessageHeader), + GNUNET_CORE_OPTION_SEND_HDR_INBOUND | + GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND); } else - GSC_SESSIONS_transmit (car, message, car->cork); + { +#if DEBUG_CORE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Delivering message of type %u to %s\n", ntohs (message->type), + GNUNET_i2s (&car->target)); +#endif + GSC_SESSIONS_transmit (car, message, tc->cork); + } } @@ -461,9 +533,10 @@ destroy_active_client_request (void *cls, const GNUNET_HashCode * key, struct GSC_ClientActiveRequest *car = value; GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (car->client_handle->requests, - &car->target.hashPubKey, - car)); + GNUNET_CONTAINER_multihashmap_remove (car-> + client_handle->requests, + &car->target.hashPubKey, + car)); GSC_SESSIONS_dequeue_request (car); GNUNET_free (car); return GNUNET_YES; @@ -477,23 +550,20 @@ destroy_active_client_request (void *cls, const GNUNET_HashCode * key, * @param client identification of the client */ static void -handle_client_disconnect (void *cls, - struct GNUNET_SERVER_Client *client) +handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) { struct GSC_Client *c; if (client == NULL) return; -#if DEBUG_CORE_CLIENT +#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p has disconnected from core service.\n", client); #endif c = find_client (client); if (c == NULL) - return; /* client never sent INIT */ - GNUNET_CONTAINER_DLL_remove (client_head, - client_tail, - c); + return; /* client never sent INIT */ + GNUNET_CONTAINER_DLL_remove (client_head, client_tail, c); if (c->requests != NULL) { GNUNET_CONTAINER_multihashmap_iterate (c->requests, @@ -501,6 +571,9 @@ handle_client_disconnect (void *cls, NULL); GNUNET_CONTAINER_multihashmap_destroy (c->requests); } +#if DEBUG_CONNECTS + GNUNET_CONTAINER_multihashmap_destroy (c->connectmap); +#endif GSC_TYPEMAP_remove (c->types, c->tcnt); GNUNET_free (c); } @@ -525,6 +598,12 @@ GSC_CLIENTS_solicit_request (struct GSC_ClientActiveRequest *car) smr.size = htons (car->msize); smr.smr_id = car->smr_id; smr.peer = car->target; +#if DEBUG_CONNECTS + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_contains (c->connectmap, + &car-> + target.hashPubKey)); +#endif send_to_client (c, &smr.header, GNUNET_NO); } @@ -541,7 +620,11 @@ void GSC_CLIENTS_reject_request (struct GSC_ClientActiveRequest *car) { GNUNET_assert (GNUNET_YES == - destroy_active_client_request (NULL, &car->target.hashPubKey, car)); + GNUNET_CONTAINER_multihashmap_remove (car-> + client_handle->requests, + &car->target.hashPubKey, + car)); + GNUNET_free (car); } @@ -556,19 +639,21 @@ GSC_CLIENTS_reject_request (struct GSC_ClientActiveRequest *car) * @param atsi_count number of entries in 'ats' array * @param tmap_old previous type map for the neighbour, NULL for disconnect * @param tmap_new updated type map for the neighbour, NULL for disconnect + * @param is_new GNUNET_YES if this is a completely new neighbour */ void -GDS_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, - const struct GSC_TypeMap *tmap_old, - const struct GSC_TypeMap *tmap_new) +GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client, + const struct GNUNET_PeerIdentity + *neighbour, + const struct GNUNET_ATS_Information + *atsi, unsigned int atsi_count, + const struct GSC_TypeMap *tmap_old, + const struct GSC_TypeMap *tmap_new) { struct ConnectNotifyMessage *cnm; size_t size; char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; - struct GNUNET_TRANSPORT_ATS_Information *a; + struct GNUNET_ATS_Information *a; struct DisconnectNotifyMessage dcm; int old_match; int new_match; @@ -576,32 +661,43 @@ GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client, old_match = GSC_TYPEMAP_test_match (tmap_old, client->types, client->tcnt); new_match = GSC_TYPEMAP_test_match (tmap_new, client->types, client->tcnt); if (old_match == new_match) - return; /* no change */ + { + GNUNET_assert (old_match == + GNUNET_CONTAINER_multihashmap_contains (client->connectmap, + &neighbour->hashPubKey)); + return; /* no change */ + } if (old_match == GNUNET_NO) { - /* send connect */ + /* send connect */ +#if DEBUG_CONNECTS + GNUNET_assert (GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (client->connectmap, + &neighbour->hashPubKey)); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_put (client->connectmap, + &neighbour->hashPubKey, + NULL, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); +#endif size = - sizeof (struct ConnectNotifyMessage) + - (atsi_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); + sizeof (struct ConnectNotifyMessage) + + (atsi_count) * sizeof (struct GNUNET_ATS_Information); if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) - { - GNUNET_break (0); - /* recovery strategy: throw away performance data */ - atsi_count = 0; - size = sizeof (struct ConnectNotifyMessage); - } + { + GNUNET_break (0); + /* recovery strategy: throw away performance data */ + atsi_count = 0; + size = sizeof (struct ConnectNotifyMessage); + } cnm = (struct ConnectNotifyMessage *) buf; cnm->header.size = htons (size); cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); cnm->ats_count = htonl (atsi_count); - a = &cnm->ats; - memcpy (a, atsi, - sizeof (struct GNUNET_TRANSPORT_ATS_Information) * atsi_count); - a[atsi_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); - a[atsi_count].value = htonl (0); -#if DEBUG_CORE_CLIENT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending `%s' message to client.\n", + a = (struct GNUNET_ATS_Information *) &cnm[1]; + memcpy (a, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); +#if DEBUG_CORE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); #endif cnm->peer = *neighbour; @@ -610,6 +706,15 @@ GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client, else { /* send disconnect */ +#if DEBUG_CONNECTS + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_contains (client->connectmap, + &neighbour->hashPubKey)); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (client->connectmap, + &neighbour->hashPubKey, + NULL)); +#endif dcm.header.size = htons (sizeof (struct DisconnectNotifyMessage)); dcm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT); dcm.reserved = htonl (0); @@ -631,27 +736,27 @@ 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, - const struct GNUNET_TRANSPORT_ATS_Information *atsi, - unsigned int atsi_count, - const struct GSC_TypeMap *tmap_old, - const struct GSC_TypeMap *tmap_new) +GSC_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity + *neighbour, + const struct GNUNET_ATS_Information + *atsi, unsigned int atsi_count, + const struct GSC_TypeMap *tmap_old, + const struct GSC_TypeMap *tmap_new) { struct GSC_Client *c; for (c = client_head; c != NULL; c = c->next) - GDS_CLIENTS_notify_client_about_neighbour (c, neighbour, atsi, - atsi_count, - tmap_old, tmap_new); + GSC_CLIENTS_notify_client_about_neighbour (c, neighbour, atsi, atsi_count, + tmap_old, tmap_new); } /** * Deliver P2P message to interested clients. Caller must have checked - * that the sending peer actually lists the given message type as one + * that the sending peer actually lists the given message type as one * of its types. * - * @param sender peer who sent us the message + * @param sender peer who sent us the message * @param atsi performance information about neighbour * @param atsi_count number of entries in 'ats' array * @param msg the message @@ -661,23 +766,23 @@ GDS_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *ne */ void GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, - const struct GNUNET_TRANSPORT_ATS_Information *atsi, - unsigned int atsi_count, - const struct GNUNET_MessageHeader *msg, - uint16_t msize, - int options) + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count, + const struct GNUNET_MessageHeader *msg, + uint16_t msize, int options) { - size_t size = msize + sizeof (struct NotifyTrafficMessage) + - atsi_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information); + size_t size = + msize + sizeof (struct NotifyTrafficMessage) + + atsi_count * sizeof (struct GNUNET_ATS_Information); char buf[size]; struct NotifyTrafficMessage *ntm; - struct GNUNET_TRANSPORT_ATS_Information *a; + struct GNUNET_ATS_Information *a; if (0 == options) { GNUNET_snprintf (buf, sizeof (buf), - gettext_noop ("# bytes of messages of type %u received"), - (unsigned int) ntohs (msg->type)); + gettext_noop ("# bytes of messages of type %u received"), + (unsigned int) ntohs (msg->type)); GNUNET_STATISTICS_update (GSC_stats, buf, msize, GNUNET_NO); } if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) @@ -690,22 +795,21 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, #if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service passes message from `%4s' of type %u to client.\n", - GNUNET_i2s (sender), - (unsigned int) ntohs (msg->type)); + 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); ntm->ats_count = htonl (atsi_count); ntm->peer = *sender; a = &ntm->ats; - memcpy (a, atsi, - sizeof (struct GNUNET_TRANSPORT_ATS_Information) * atsi_count); - a[atsi_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); + memcpy (a, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); + a[atsi_count].type = htonl (GNUNET_ATS_ARRAY_TERMINATOR); a[atsi_count].value = htonl (0); memcpy (&a[atsi_count + 1], msg, msize); - send_to_all_clients (&ntm->header, GNUNET_YES, - options, ntohs (msg->type)); + send_to_all_clients (sender, &ntm->header, GNUNET_YES, options, + ntohs (msg->type)); } @@ -752,10 +856,13 @@ GSC_CLIENTS_done () { struct GSC_Client *c; - while (NULL != (c = client_head)) + while (NULL != (c = client_head)) handle_client_disconnect (NULL, c->client_handle); - GNUNET_SERVER_notification_context_destroy (notifier); - notifier = NULL; + if (NULL != notifier) + { + GNUNET_SERVER_notification_context_destroy (notifier); + notifier = NULL; + } GNUNET_SERVER_mst_destroy (client_mst); client_mst = NULL; }