From c1ff578c693e4e45125ead915dc515bb141883ec Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 20 Oct 2013 17:58:46 +0000 Subject: -allow namestore to monitor ALL zones, and to optionally only monitor changes --- src/include/gnunet_namestore_service.h | 20 ++++++++----- src/namestore/gnunet-namestore.c | 1 + src/namestore/gnunet-service-namestore.c | 34 ++++++++++++++++------ src/namestore/namestore.h | 8 ++++- src/namestore/namestore_api_monitor.c | 31 ++++++++++++-------- src/namestore/test_namestore_api_monitoring.c | 3 +- .../test_namestore_api_monitoring_existing.c | 9 +++--- 7 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h index c85330681..9aa51ca11 100644 --- a/src/include/gnunet_namestore_service.h +++ b/src/include/gnunet_namestore_service.h @@ -247,15 +247,20 @@ typedef void (*GNUNET_NAMESTORE_RecordsSynchronizedCallback)(void *cls); /** - * Begin monitoring a zone for changes. Will first call the @a monitor function - * on all existing records in the selected zone(s), then calls @a sync_cb, - * and then calls the @a monitor whenever a record changes. If the namestore - * disconnects, the @a monitor function is called with a disconnect event; if - * the connection is re-established, the process begins from the start (all - * existing records, sync, then updates). + * Begin monitoring a zone for changes. Will first call the @a + * monitor function on all existing records in the selected zone(s) if + * @a iterate_first is #GNUNET_YES. In any case, we will then call @a + * sync_cb, and then afterwards call the @a monitor whenever a record + * changes. If the namestore disconnects, the @a monitor function is + * called with a disconnect event; if the connection is + * re-established, the process begins from the start (depending on @a + * iterate_first, we first do all existing records, then @a sync, then + * updates). * * @param cfg configuration to use to connect to namestore - * @param zone zone to monitor + * @param zone zone to monitor, NULL for all zones + * @param iterate_first #GNUNET_YES to first iterate over all existing records, + * #GNUNET_NO to only return changes that happen from now on * @param monitor function to call on zone changes * @param sync_cb function called when we're in sync with the namestore * @param cls closure for @a monitor and @a sync_cb @@ -264,6 +269,7 @@ typedef void (*GNUNET_NAMESTORE_RecordsSynchronizedCallback)(void *cls); struct GNUNET_NAMESTORE_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + int iterate_first, GNUNET_NAMESTORE_RecordMonitor monitor, GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb, void *cls); diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index 36aae6056..f23988df6 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c @@ -718,6 +718,7 @@ testservice_task (void *cls, { zm = GNUNET_NAMESTORE_zone_monitor_start (cfg, &zone_pkey, + GNUNET_YES, &display_record, &sync_cb, NULL); diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index 53a685c63..b0704d7bd 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c @@ -143,11 +143,6 @@ struct ZoneMonitor */ struct GNUNET_CRYPTO_EcdsaPrivateKey zone; - /** - * The operation id fot the zone iteration in the response for the client - */ - uint32_t request_id; - /** * Task active during initial iteration. */ @@ -679,17 +674,36 @@ handle_record_store (void *cls, if (GNUNET_OK == res) { for (zm = monitor_head; NULL != zm; zm = zm->next) + { if ( (0 == memcmp (&rp_msg->private_key, &zm->zone, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) || (0 == memcmp (&zm->zone, &zero, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Notifying monitor about changes under label `%s'\n", + conv_name); send_lookup_response (monitor_nc, zm->nc->client, - zm->request_id, + 0, &rp_msg->private_key, conv_name, rd_count, rd); + } + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Monitor is for another zone\n"); + } + if (NULL == monitor_head) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No monitors active\n"); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Error storing record: %d\n", + res); } } if (GNUNET_OK == res) @@ -1186,7 +1200,7 @@ monitor_iterate_cb (void *cls, } send_lookup_response (monitor_nc, zm->nc->client, - zm->request_id, + 0, zone_key, name, rd_count, @@ -1215,7 +1229,6 @@ handle_monitor_start (void *cls, "ZONE_MONITOR_START"); zis_msg = (const struct ZoneMonitorStartMessage *) message; zm = GNUNET_new (struct ZoneMonitor); - zm->request_id = ntohl (zis_msg->gns_header.r_id); zm->offset = 0; zm->nc = client_lookup (client); zm->zone = zis_msg->zone; @@ -1224,7 +1237,10 @@ handle_monitor_start (void *cls, GNUNET_SERVER_disable_receive_done_warning (client); GNUNET_SERVER_notification_context_add (monitor_nc, client); - zm->task = GNUNET_SCHEDULER_add_now (&monitor_next, zm); + if (GNUNET_YES == ntohs (zis_msg->iterate_first)) + zm->task = GNUNET_SCHEDULER_add_now (&monitor_next, zm); + else + monitor_sync (zm); } diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index b95358fa4..bd0cf82cc 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -353,7 +353,13 @@ struct ZoneMonitorStartMessage /** * Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START */ - struct GNUNET_NAMESTORE_Header gns_header; + struct GNUNET_MessageHeader header; + + /** + * #GNUNET_YES to first iterate over all records, + * #GNUNET_NO to only monitor changes.o + */ + uint32_t iterate_first GNUNET_PACKED; /** * Zone key. diff --git a/src/namestore/namestore_api_monitor.c b/src/namestore/namestore_api_monitor.c index 076add1eb..4319f574f 100644 --- a/src/namestore/namestore_api_monitor.c +++ b/src/namestore/namestore_api_monitor.c @@ -75,6 +75,11 @@ struct GNUNET_NAMESTORE_ZoneMonitor */ struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + /** + * Do we first iterate over all existing records? + */ + int iterate_first; + }; @@ -228,9 +233,9 @@ transmit_monitor_message (void *cls, reconnect (zm); return 0; } - sm.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START); - sm.gns_header.header.size = htons (sizeof (struct ZoneMonitorStartMessage)); - sm.gns_header.r_id = htonl (0); + sm.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START); + sm.header.size = htons (sizeof (struct ZoneMonitorStartMessage)); + sm.iterate_first = htonl (zm->iterate_first); sm.zone = zm->zone; memcpy (buf, &sm, sizeof (sm)); GNUNET_CLIENT_receive (zm->h, @@ -242,20 +247,24 @@ transmit_monitor_message (void *cls, /** - * Begin monitoring a zone for changes. Will first call the 'monitor' function - * on all existing records in the selected zone(s) and then call it whenever - * a record changes. + * Begin monitoring a zone for changes. If @a iterate_first is set, + * we Will first call the @a monitor function on all existing records + * in the selected zone(s). In any case, we will call @a sync and + * afterwards call @a monitor whenever a record changes. * * @param cfg configuration to use to connect to namestore * @param zone zone to monitor + * @param iterate_first #GNUNET_YES to first iterate over all existing records, + * #GNUNET_NO to only return changes that happen from now on * @param monitor function to call on zone changes * @param sync_cb function called when we're in sync with the namestore - * @param cls closure for 'monitor' and 'sync_cb' + * @param cls closure for @a monitor and @a sync_cb * @return handle to stop monitoring */ struct GNUNET_NAMESTORE_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + int iterate_first, GNUNET_NAMESTORE_RecordMonitor monitor, GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb, void *cls) @@ -263,16 +272,14 @@ GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *c struct GNUNET_NAMESTORE_ZoneMonitor *zm; struct GNUNET_CLIENT_Connection *client; - if (NULL == zone) - return NULL; if (NULL == (client = GNUNET_CLIENT_connect ("namestore", cfg))) return NULL; - - zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor); zm->cfg = cfg; zm->h = client; - zm->zone = *zone; + if (NULL != zone) + zm->zone = *zone; + zm->iterate_first = iterate_first; zm->monitor = monitor; zm->sync_cb = sync_cb; zm->cls = cls; diff --git a/src/namestore/test_namestore_api_monitoring.c b/src/namestore/test_namestore_api_monitoring.c index 0bd1e1350..c9b182fc8 100644 --- a/src/namestore/test_namestore_api_monitoring.c +++ b/src/namestore/test_namestore_api_monitoring.c @@ -274,7 +274,8 @@ run (void *cls, /* Start monitoring */ zm = GNUNET_NAMESTORE_zone_monitor_start (cfg, - privkey, + privkey, + GNUNET_YES, &zone_proc, NULL, NULL); diff --git a/src/namestore/test_namestore_api_monitoring_existing.c b/src/namestore/test_namestore_api_monitoring_existing.c index bab857def..16e4e4157 100644 --- a/src/namestore/test_namestore_api_monitoring_existing.c +++ b/src/namestore/test_namestore_api_monitoring_existing.c @@ -237,10 +237,11 @@ put_cont (void *cls, int32_t success, const char *emsg) { /* Start monitoring */ zm = GNUNET_NAMESTORE_zone_monitor_start (cfg, - privkey, - &zone_proc, - NULL, - NULL); + privkey, + GNUNET_YES, + &zone_proc, + NULL, + NULL); if (NULL == zm) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone monitor\n"); -- cgit v1.2.3