From 474599b488b51b998464321ff25219d366b31e94 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 24 Sep 2016 20:29:31 +0000 Subject: [PATCH] convert peerinfo to new service MQ API --- src/peerinfo/gnunet-service-peerinfo.c | 632 +++++++++++++------------ 1 file changed, 322 insertions(+), 310 deletions(-) diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index 07a7d704c..bc4a2a10d 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2001-2014 GNUnet e.V. + Copyright (C) 2001-2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -69,22 +69,6 @@ struct HostEntry }; -/** - * Transmit context for GET requests - */ -struct TransmitContext -{ - /** - * Server transmit context - */ - struct GNUNET_SERVER_TransmitContext *tc; - - /** - * Include friend only HELLOs #GNUNET_YES or #GNUNET_NO - */ - int friend_only; -}; - /** * Result of reading a file @@ -103,33 +87,6 @@ struct ReadHostFileContext }; -/** - * Client notification context - */ -struct NotificationContext -{ - /** - * Next in DLL - */ - struct NotificationContext *prev; - - /** - * Previous in DLL - */ - struct NotificationContext *next; - - /** - * Server client - */ - struct GNUNET_SERVER_Client *client; - - /** - * Interested in friend only HELLO? - */ - int include_friend_only; -}; - - /** * The in-memory list of known hosts, mapping of * host IDs to 'struct HostEntry*' values. @@ -139,7 +96,13 @@ static struct GNUNET_CONTAINER_MultiPeerMap *hostmap; /** * Clients to immediately notify about all changes. */ -static struct GNUNET_SERVER_NotificationContext *notify_list; +static struct GNUNET_NotificationContext *notify_list; + +/** + * Clients to immediately notify about all changes, + * even for friend-only HELLOs. + */ +static struct GNUNET_NotificationContext *notify_friend_only_list; /** * Directory where the hellos are stored in (peerinfo/) @@ -151,16 +114,6 @@ static char *networkIdDirectory; */ static struct GNUNET_STATISTICS_Handle *stats; -/** - * DLL of notification contexts: head - */ -static struct NotificationContext *nc_head; - -/** - * DLL of notification contexts: tail - */ -static struct NotificationContext *nc_tail; - /** * Handle for task to run #cron_clean_data_hosts() */ @@ -189,17 +142,17 @@ make_info_message (const struct HostEntry *he, size_t hs; if (GNUNET_YES == include_friend_only) - src = he->friend_only_hello; + src = he->friend_only_hello; else - src = he->hello; - + src = he->hello; hs = (NULL == src) ? 0 : GNUNET_HELLO_size (src); im = GNUNET_malloc (sizeof (struct InfoMessage) + hs); im->header.size = htons (hs + sizeof (struct InfoMessage)); im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); im->peer = he->identity; - if (NULL != src) - GNUNET_memcpy (&im[1], src, hs); + GNUNET_memcpy (&im[1], + src, + hs); return im; } @@ -264,7 +217,10 @@ get_host_filename (const struct GNUNET_PeerIdentity *id) if (NULL == networkIdDirectory) return NULL; - GNUNET_asprintf (&fn, "%s%s%s", networkIdDirectory, DIR_SEPARATOR_STR, + GNUNET_asprintf (&fn, + "%s%s%s", + networkIdDirectory, + DIR_SEPARATOR_STR, GNUNET_i2s_full (id)); return fn; } @@ -281,31 +237,21 @@ notify_all (struct HostEntry *entry) { struct InfoMessage *msg_pub; struct InfoMessage *msg_friend; - struct NotificationContext *cur; - msg_pub = make_info_message (entry, GNUNET_NO); - msg_friend = make_info_message (entry, GNUNET_YES); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying all clients about peer `%s'\n", GNUNET_i2s(&entry->identity)); - for (cur = nc_head; NULL != cur; cur = cur->next) - { - if (GNUNET_NO == cur->include_friend_only) - { - GNUNET_SERVER_notification_context_unicast (notify_list, - cur->client, - &msg_pub->header, - GNUNET_NO); - } - if (GNUNET_YES == cur->include_friend_only) - { - GNUNET_SERVER_notification_context_unicast (notify_list, - cur->client, - &msg_friend->header, - GNUNET_NO); - } - } + msg_pub = make_info_message (entry, + GNUNET_NO); + GNUNET_notification_context_broadcast (notify_list, + &msg_pub->header, + GNUNET_NO); GNUNET_free (msg_pub); + msg_friend = make_info_message (entry, + GNUNET_YES); + GNUNET_notification_context_broadcast (notify_friend_only_list, + &msg_friend->header, + GNUNET_NO); GNUNET_free (msg_friend); } @@ -351,7 +297,9 @@ read_host_file (const char *fn, if (GNUNET_YES != GNUNET_DISK_file_test (fn)) return; - size_total = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); + size_total = GNUNET_DISK_fn_read (fn, + buffer, + sizeof (buffer)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes from `%s'\n", (int) size_total, @@ -360,7 +308,8 @@ read_host_file (const char *fn, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse HELLO in file `%s': %s\n"), - fn, "Fail has invalid size"); + fn, + "File has invalid size"); if ( (GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn)) && (ENOENT != errno) ) @@ -392,9 +341,9 @@ read_host_file (const char *fn, } else { - if ((GNUNET_YES == unlink_garbage) && - (0 != TRUNCATE (fn, read_pos)) && - (ENOENT != errno) ) + if ( (GNUNET_YES == unlink_garbage) && + (0 != TRUNCATE (fn, read_pos)) && + (ENOENT != errno) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "truncate", fn); @@ -403,8 +352,10 @@ read_host_file (const char *fn, } now = GNUNET_TIME_absolute_get (); - hello_clean = GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, - &discard_expired, &now); + hello_clean = GNUNET_HELLO_iterate_addresses (hello, + GNUNET_YES, + &discard_expired, + &now); if (NULL == hello_clean) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -419,8 +370,10 @@ read_host_file (const char *fn, return; } left = 0; - (void) GNUNET_HELLO_iterate_addresses (hello_clean, GNUNET_NO, - &count_addresses, &left); + (void) GNUNET_HELLO_iterate_addresses (hello_clean, + GNUNET_NO, + &count_addresses, + &left); if (0 == left) { @@ -482,13 +435,16 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) struct ReadHostFileContext r; char *fn; - entry = GNUNET_CONTAINER_multipeermap_get (hostmap, identity); + entry = GNUNET_CONTAINER_multipeermap_get (hostmap, + identity); if (NULL == entry) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer `%s'\n", GNUNET_i2s (identity)); - GNUNET_STATISTICS_update (stats, gettext_noop ("# peers known"), 1, + GNUNET_STATISTICS_update (stats, + gettext_noop ("# peers known"), + 1, GNUNET_NO); entry = GNUNET_new (struct HostEntry); entry->identity = *identity; @@ -501,11 +457,15 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) fn = get_host_filename (identity); if (NULL != fn) { - read_host_file (fn, GNUNET_YES, &r); + read_host_file (fn, + GNUNET_YES, + &r); if (NULL != r.hello) - update_hello (identity, r.hello); + update_hello (identity, + r.hello); if (NULL != r.friend_only_hello) - update_hello (identity, r.friend_only_hello); + update_hello (identity, + r.friend_only_hello); GNUNET_free_non_null (r.hello); GNUNET_free_non_null (r.friend_only_hello); GNUNET_free (fn); @@ -580,18 +540,25 @@ hosts_directory_scan_callback (void *cls, if (GNUNET_YES != GNUNET_DISK_file_test (fullname)) return GNUNET_OK; /* ignore non-files */ - filename = strrchr (fullname, DIR_SEPARATOR); - if ((NULL == filename) || (1 > strlen (filename))) + filename = strrchr (fullname, + DIR_SEPARATOR); + if ( (NULL == filename) || + (1 > strlen (filename)) ) filename = fullname; else filename ++; - read_host_file (fullname, dsc->remove_files, &r); - if ( (NULL == r.hello) && (NULL == r.friend_only_hello)) + read_host_file (fullname, + dsc->remove_files, + &r); + if ( (NULL == r.hello) && + (NULL == r.friend_only_hello)) return GNUNET_OK; if (NULL != r.friend_only_hello) { - if (GNUNET_OK != GNUNET_HELLO_get_id (r.friend_only_hello, &id_friend)) + if (GNUNET_OK != + GNUNET_HELLO_get_id (r.friend_only_hello, + &id_friend)) if (GNUNET_YES == dsc->remove_files) { remove_garbage (fullname); @@ -601,7 +568,9 @@ hosts_directory_scan_callback (void *cls, } if (NULL != r.hello) { - if (GNUNET_OK != GNUNET_HELLO_get_id (r.hello, &id_public)) + if (GNUNET_OK != + GNUNET_HELLO_get_id (r.hello, + &id_public)) if (GNUNET_YES == dsc->remove_files) { remove_garbage (fullname); @@ -610,8 +579,11 @@ hosts_directory_scan_callback (void *cls, id = id_public; } - if ( (NULL != r.hello) && (NULL != r.friend_only_hello) && - (0 != memcmp (&id_friend, &id_public, sizeof (id_friend))) ) + if ( (NULL != r.hello) && + (NULL != r.friend_only_hello) && + (0 != memcmp (&id_friend, + &id_public, + sizeof (id_friend))) ) { /* HELLOs are not for the same peer */ GNUNET_break (0); @@ -683,8 +655,10 @@ cron_scan_directory_data_hosts (void *cls) _("Scanning directory `%s'\n"), networkIdDirectory); GNUNET_DISK_directory_scan (networkIdDirectory, - &hosts_directory_scan_callback, &dsc); - if ((0 == dsc.matched) && (0 == (++retries & 31))) + &hosts_directory_scan_callback, + &dsc); + if ( (0 == dsc.matched) && + (0 == (++retries & 31)) ) GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, _("Still no peers found in `%s'!\n"), networkIdDirectory); @@ -712,8 +686,10 @@ update_friend_hello (const struct GNUNET_HELLO_Message *hello, if (NULL != friend_hello) { - res = GNUNET_HELLO_merge (hello, friend_hello); - GNUNET_assert (GNUNET_YES == GNUNET_HELLO_is_friend_only (res)); + res = GNUNET_HELLO_merge (hello, + friend_hello); + GNUNET_assert (GNUNET_YES == + GNUNET_HELLO_is_friend_only (res)); return res; } @@ -783,8 +759,11 @@ update_hello (const struct GNUNET_PeerIdentity *peer, } else { - mrg = GNUNET_HELLO_merge ((*dest), hello); - delta = GNUNET_HELLO_equals (mrg, (*dest), GNUNET_TIME_absolute_get ()); + mrg = GNUNET_HELLO_merge ((*dest), + hello); + delta = GNUNET_HELLO_equals (mrg, + (*dest), + GNUNET_TIME_absolute_get ()); if (delta.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) { /* no differences, just ignore the update */ @@ -803,7 +782,8 @@ update_hello (const struct GNUNET_PeerIdentity *peer, (GNUNET_NO == friend_hello_type) ) { /* Update friend only hello */ - mrg = update_friend_hello (host->hello, host->friend_only_hello); + mrg = update_friend_hello (host->hello, + host->friend_only_hello); if (NULL != host->friend_only_hello) GNUNET_free (host->friend_only_hello); host->friend_only_hello = mrg; @@ -862,8 +842,8 @@ update_hello (const struct GNUNET_PeerIdentity *peer, if (GNUNET_YES == store_hello) { GNUNET_memcpy (buffer, - host->hello, - GNUNET_HELLO_size (host->hello)); + host->hello, + GNUNET_HELLO_size (host->hello)); pos += GNUNET_HELLO_size (host->hello); } if (GNUNET_YES == store_friend_hello) @@ -886,7 +866,8 @@ update_hello (const struct GNUNET_PeerIdentity *peer, "Stored %s %s HELLO in %s with total size %u\n", (GNUNET_YES == store_friend_hello) ? "friend-only": "", (GNUNET_YES == store_hello) ? "public": "", - fn, size); + fn, + size); GNUNET_free (buffer); } } @@ -895,6 +876,23 @@ update_hello (const struct GNUNET_PeerIdentity *peer, } +/** + * Closure for #add_to_tc() + */ +struct TransmitContext +{ + /** + * Client to transmit to + */ + struct GNUNET_SERVICE_Client *client; + + /** + * Include friend only HELLOs #GNUNET_YES or #GNUNET_NO + */ + int friend_only; +}; + + /** * Do transmit info about peer to given host. * @@ -912,10 +910,9 @@ add_to_tc (void *cls, struct HostEntry *pos = value; struct InfoMessage *im; uint16_t hs; - char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; + struct GNUNET_MQ_Envelope *env; hs = 0; - im = (struct InfoMessage *) buf; if ( (NULL != pos->hello) && (GNUNET_NO == tc->friend_only) ) @@ -924,10 +921,16 @@ add_to_tc (void *cls, hs = GNUNET_HELLO_size (pos->hello); GNUNET_assert (hs < GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct InfoMessage)); - GNUNET_memcpy (&im[1], pos->hello, hs); + env = GNUNET_MQ_msg_extra (im, + hs, + GNUNET_MESSAGE_TYPE_PEERINFO_INFO); + GNUNET_memcpy (&im[1], + pos->hello, + hs); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending public HELLO with size %u for peer `%4s'\n", - hs, GNUNET_i2s (key)); + "Sending public HELLO with size %u for peer `%s'\n", + hs, + GNUNET_i2s (key)); } else if ( (NULL != pos->friend_only_hello) && (GNUNET_YES == tc->friend_only) ) @@ -936,24 +939,28 @@ add_to_tc (void *cls, hs = GNUNET_HELLO_size (pos->friend_only_hello); GNUNET_assert (hs < GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct InfoMessage)); - GNUNET_memcpy (&im[1], pos->friend_only_hello, hs); + env = GNUNET_MQ_msg_extra (im, + hs, + GNUNET_MESSAGE_TYPE_PEERINFO_INFO); + GNUNET_memcpy (&im[1], + pos->friend_only_hello, + hs); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending friend-only HELLO with size %u for peer `%4s'\n", + "Sending friend-only HELLO with size %u for peer `%s'\n", hs, GNUNET_i2s (key)); } else { + env = GNUNET_MQ_msg (im, + GNUNET_MESSAGE_TYPE_PEERINFO_INFO); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding no HELLO for peer `%s'\n", GNUNET_i2s (key)); } - - im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); - im->header.size = htons (sizeof (struct InfoMessage) + hs); - im->reserved = htonl (0); im->peer = pos->identity; - GNUNET_SERVER_transmit_context_append_message (tc->tc, &im->header); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (tc->client), + env); return GNUNET_YES; } @@ -1004,23 +1011,28 @@ discard_hosts_helper (void *cls, if (0 != UNLINK (fn)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, - "unlink", fn); + "unlink", + fn); GNUNET_free (writebuffer); return GNUNET_OK; } new_hello = GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, - &discard_expired, now); + &discard_expired, + now); cnt = 0; if (NULL != new_hello) (void) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, - &count_addresses, &cnt); + &count_addresses, + &cnt); if ( (NULL != new_hello) && (0 < cnt) ) { /* Store new HELLO to write it when done */ new_hello_size = GNUNET_HELLO_size (new_hello); - GNUNET_memcpy (&writebuffer[write_pos], new_hello, new_hello_size); + GNUNET_memcpy (&writebuffer[write_pos], + new_hello, + new_hello_size); write_pos += new_hello_size; } read_pos += cur_hello_size; @@ -1073,167 +1085,170 @@ cron_clean_data_hosts (void *cls) /** - * Handle HELLO-message. + * Check HELLO-message. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param hello the actual message + * @return #GNUNET_OK if @a hello is well-formed */ -static void -handle_hello (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_hello (void *cls, + const struct GNUNET_HELLO_Message *hello) { - const struct GNUNET_HELLO_Message *hello; struct GNUNET_PeerIdentity pid; - hello = (const struct GNUNET_HELLO_Message *) message; - if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid)) + if (GNUNET_OK != + GNUNET_HELLO_get_id (hello, + &pid)) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * Handle HELLO-message. + * + * @param cls identification of the client + * @param hello the actual message + */ +static void +handle_hello (void *cls, + const struct GNUNET_HELLO_Message *hello) +{ + struct GNUNET_SERVICE_Client *client = cls; + struct GNUNET_PeerIdentity pid; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "`%s' message received for peer `%4s'\n", - "HELLO", + "HELLO message received for peer `%s'\n", GNUNET_i2s (&pid)); + GNUNET_assert (GNUNET_OK == + GNUNET_HELLO_get_id (hello, + &pid)); add_host_to_known_hosts (&pid); - update_hello (&pid, hello); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + update_hello (&pid, + hello); + GNUNET_SERVICE_client_continue (client); } /** * Handle GET-message. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param lpm the actual message */ static void handle_get (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) + const struct ListPeerMessage *lpm) { - const struct ListPeerMessage *lpm; + struct GNUNET_SERVICE_Client *client = cls; struct TransmitContext tcx; + struct GNUNET_MessageHeader *msg; + struct GNUNET_MQ_Envelope *env; - lpm = (const struct ListPeerMessage *) message; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "`%s' message received for peer `%4s'\n", - "GET", + "GET message received for peer `%s'\n", GNUNET_i2s (&lpm->peer)); tcx.friend_only = ntohl (lpm->include_friend_only); - tcx.tc = GNUNET_SERVER_transmit_context_create (client); - GNUNET_CONTAINER_multipeermap_get_multiple (hostmap, &lpm->peer, - &add_to_tc, &tcx); - GNUNET_SERVER_transmit_context_append_data (tcx.tc, NULL, 0, - GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END); - GNUNET_SERVER_transmit_context_run (tcx.tc, GNUNET_TIME_UNIT_FOREVER_REL); + tcx.client = client; + GNUNET_CONTAINER_multipeermap_get_multiple (hostmap, + &lpm->peer, + &add_to_tc, + &tcx); + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), + env); + GNUNET_SERVICE_client_continue (client); } /** * Handle GET-ALL-message. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param lapm the actual message */ static void -handle_get_all (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +handle_get_all (void *cls, + const struct ListAllPeersMessage *lapm) { - const struct ListAllPeersMessage *lapm; + struct GNUNET_SERVICE_Client *client = cls; struct TransmitContext tcx; + struct GNUNET_MQ_Envelope *env; + struct GNUNET_MessageHeader *msg; - lapm = (const struct ListAllPeersMessage *) message; - tcx.friend_only = ntohl (lapm->include_friend_only); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "`%s' message received\n", - "GET_ALL"); - GNUNET_SERVER_disable_receive_done_warning (client); - tcx.tc = GNUNET_SERVER_transmit_context_create (client); + "GET_ALL message received\n"); + tcx.friend_only = ntohl (lapm->include_friend_only); + tcx.client = client; GNUNET_CONTAINER_multipeermap_iterate (hostmap, &add_to_tc, &tcx); - GNUNET_SERVER_transmit_context_append_data (tcx.tc, NULL, 0, - GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END); - GNUNET_SERVER_transmit_context_run (tcx.tc, GNUNET_TIME_UNIT_FOREVER_REL); + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), + env); + GNUNET_SERVICE_client_continue (client); } - /** - * Pass the given client the information we have in the respective - * host entry; the client is already in the notification context. + * Handle NOTIFY-message. * - * @param cls the `struct GNUNET_SERVER_Client` to notify - * @param key key for the value (unused) - * @param value the `struct HostEntry` to notify the client about - * @return #GNUNET_YES (always, continue to iterate) + * @param cls identification of the client + * @param nm the actual message */ -static int -do_notify_entry (void *cls, - const struct GNUNET_PeerIdentity *key, - void *value) +static void +handle_notify (void *cls, + const struct NotifyMessage *nm) { - struct NotificationContext *nc = cls; - struct HostEntry *he = value; - struct InfoMessage *msg; - - if ( (NULL == he->hello) && - (GNUNET_NO == nc->include_friend_only) ) - { - /* We have no public hello */ - return GNUNET_YES; - } - - if ( (NULL == he->friend_only_hello) && - (GNUNET_YES == nc->include_friend_only) ) - { - /* We have no friend hello */ - return GNUNET_YES; - } + struct GNUNET_SERVICE_Client *client = cls; + struct GNUNET_MQ_Handle *mq; + struct TransmitContext tcx; + struct GNUNET_MQ_Envelope *env; + struct GNUNET_MessageHeader *msg; - msg = make_info_message (he, nc->include_friend_only); - GNUNET_SERVER_notification_context_unicast (notify_list, - nc->client, - &msg->header, - GNUNET_NO); - GNUNET_free (msg); - return GNUNET_YES; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "NOTIFY message received\n"); + mq = GNUNET_SERVICE_client_get_mq (client); + GNUNET_SERVICE_client_mark_monitor (client); + if (ntohl (nm->include_friend_only)) + GNUNET_notification_context_add (notify_friend_only_list, + mq); + else + GNUNET_notification_context_add (notify_list, + mq); + tcx.friend_only = ntohl (nm->include_friend_only); + tcx.client = client; + GNUNET_CONTAINER_multipeermap_iterate (hostmap, + &add_to_tc, + &tcx); + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), + env); + GNUNET_SERVICE_client_continue (client); } /** - * Handle NOTIFY-message. + * Client connect callback * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls unused + * @param client server client + * @param mq for @a client + * @return @a client */ -static void -handle_notify (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static void * +client_connect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + struct GNUNET_MQ_Handle *mq) { - struct NotifyMessage *nm = (struct NotifyMessage *) message; - struct NotificationContext *nc; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "`%s' message received\n", - "NOTIFY"); - nc = GNUNET_new (struct NotificationContext); - nc->client = client; - nc->include_friend_only = ntohl (nm->include_friend_only); - - GNUNET_CONTAINER_DLL_insert (nc_head, nc_tail, nc); - GNUNET_SERVER_client_mark_monitor (client); - GNUNET_SERVER_notification_context_add (notify_list, client); - GNUNET_CONTAINER_multipeermap_iterate (hostmap, &do_notify_entry, nc); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + return client; } @@ -1242,20 +1257,14 @@ handle_notify (void *cls, * * @param cls unused * @param client server client + * @param app_ctx should be @a client */ static void -disconnect_cb (void *cls, - struct GNUNET_SERVER_Client *client) +client_disconnect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + void *app_ctx) { - struct NotificationContext *cur; - - for (cur = nc_head; NULL != cur; cur = cur->next) - if (cur->client == client) - break; - if (NULL == cur) - return; - GNUNET_CONTAINER_DLL_remove (nc_head, nc_tail, cur); - GNUNET_free (cur); + GNUNET_assert (app_ctx == client); } @@ -1289,25 +1298,19 @@ free_host_entry (void *cls, static void shutdown_task (void *cls) { - struct NotificationContext *cur; - struct NotificationContext *next; - - GNUNET_SERVER_notification_context_destroy (notify_list); + GNUNET_notification_context_destroy (notify_list); notify_list = NULL; + GNUNET_notification_context_destroy (notify_friend_only_list); + notify_friend_only_list = NULL; - for (cur = nc_head; NULL != cur; cur = next) - { - next = cur->next; - GNUNET_CONTAINER_DLL_remove (nc_head, nc_tail, cur); - GNUNET_free (cur); - } GNUNET_CONTAINER_multipeermap_iterate (hostmap, &free_host_entry, NULL); GNUNET_CONTAINER_multipeermap_destroy (hostmap); if (NULL != stats) { - GNUNET_STATISTICS_destroy (stats, GNUNET_NO); + GNUNET_STATISTICS_destroy (stats, + GNUNET_NO); stats = NULL; } if (NULL != cron_clean) @@ -1320,6 +1323,11 @@ shutdown_task (void *cls) GNUNET_SCHEDULER_cancel (cron_scan); cron_scan = NULL; } + if (NULL != networkIdDirectory) + { + GNUNET_free (networkIdDirectory); + networkIdDirectory = NULL; + } } @@ -1327,37 +1335,37 @@ shutdown_task (void *cls) * Start up peerinfo service. * * @param cls closure - * @param server the initialized server * @param cfg configuration to use + * @param service the initialized service */ static void run (void *cls, - struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *cfg) + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_SERVICE_Handle *service) { - static const struct GNUNET_SERVER_MessageHandler handlers[] = { - {&handle_hello, NULL, GNUNET_MESSAGE_TYPE_HELLO, 0}, - {&handle_get, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET, - sizeof (struct ListPeerMessage)}, - {&handle_get_all, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, - sizeof (struct ListAllPeersMessage)}, - {&handle_notify, NULL, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY, - sizeof (struct NotifyMessage)}, - {NULL, NULL, 0, 0} - }; char *peerdir; char *ip; struct DirScanContext dsc; int noio; int use_included; - hostmap = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES); - stats = GNUNET_STATISTICS_create ("peerinfo", cfg); - notify_list = GNUNET_SERVER_notification_context_create (server, 0); - noio = GNUNET_CONFIGURATION_get_value_yesno (cfg, "peerinfo", "NO_IO"); - use_included = GNUNET_CONFIGURATION_get_value_yesno (cfg, - "peerinfo", - "USE_INCLUDED_HELLOS"); + hostmap + = GNUNET_CONTAINER_multipeermap_create (1024, + GNUNET_YES); + stats + = GNUNET_STATISTICS_create ("peerinfo", + cfg); + notify_list + = GNUNET_notification_context_create (0); + notify_friend_only_list + = GNUNET_notification_context_create (0); + noio = GNUNET_CONFIGURATION_get_value_yesno (cfg, + "peerinfo", + "NO_IO"); + use_included + = GNUNET_CONFIGURATION_get_value_yesno (cfg, + "peerinfo", + "USE_INCLUDED_HELLOS"); if (GNUNET_SYSERR == use_included) use_included = GNUNET_NO; GNUNET_SCHEDULER_add_shutdown (&shutdown_task, @@ -1365,7 +1373,8 @@ run (void *cls, if (GNUNET_YES != noio) { GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_filename (cfg, "peerinfo", + GNUNET_CONFIGURATION_get_value_filename (cfg, + "peerinfo", "HOSTS", &networkIdDirectory)); if (GNUNET_OK != @@ -1375,20 +1384,22 @@ run (void *cls, return; } - cron_scan = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, - &cron_scan_directory_data_hosts, - NULL); + cron_scan + = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, + &cron_scan_directory_data_hosts, + NULL); - cron_clean = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, - &cron_clean_data_hosts, - NULL); + cron_clean + = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, + &cron_clean_data_hosts, + NULL); if (GNUNET_YES == use_included) { ip = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); GNUNET_asprintf (&peerdir, "%shellos", ip); - GNUNET_free(ip); + GNUNET_free (ip); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Importing HELLOs from `%s'\n"), @@ -1403,39 +1414,40 @@ run (void *cls, } else { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - _("Skipping import of included HELLOs\n")); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Skipping import of included HELLOs\n")); } } - GNUNET_SERVER_add_handlers (server, handlers); - GNUNET_SERVER_disconnect_notify (server, - &disconnect_cb, - NULL); } /** - * The main function for the peerinfo service. - * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error + * Define "main" method using service macro. */ -int -main (int argc, - char *const *argv) -{ - int ret; - - ret = - (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, - "peerinfo", - GNUNET_SERVICE_OPTION_NONE, - &run, NULL)) ? 0 : 1; - GNUNET_free_non_null (networkIdDirectory); - return ret; -} +GNUNET_SERVICE_MAIN +("peerinfo", + GNUNET_SERVICE_OPTION_NONE, + &run, + &client_connect_cb, + &client_disconnect_cb, + NULL, + GNUNET_MQ_hd_var_size (hello, + GNUNET_MESSAGE_TYPE_HELLO, + struct GNUNET_HELLO_Message, + NULL), + GNUNET_MQ_hd_fixed_size (get, + GNUNET_MESSAGE_TYPE_PEERINFO_GET, + struct ListPeerMessage, + NULL), + GNUNET_MQ_hd_fixed_size (get_all, + GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, + struct ListAllPeersMessage, + NULL), + GNUNET_MQ_hd_fixed_size (notify, + GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY, + struct NotifyMessage, + NULL), + GNUNET_MQ_handler_end ()); /* end of gnunet-service-peerinfo.c */ -- 2.25.1