summaryrefslogtreecommitdiff
path: root/src/or/hs_service.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2017-02-03 15:29:31 -0500
committerNick Mathewson <nickm@torproject.org>2017-08-08 20:29:33 -0400
commit0f104ddce578c52d604931c595b28aa61a184b40 (patch)
tree25af5f25d05d12df11c543d6755e30a148ecc0c2 /src/or/hs_service.c
parent9052530bdde9f03da883dfb70fe261ea7d0e1b4d (diff)
downloadtor-0f104ddce578c52d604931c595b28aa61a184b40.tar.gz
tor-0f104ddce578c52d604931c595b28aa61a184b40.zip
prop224: Scheduled events for service
Add the main loop entry point to the HS service subsystem. It is run every second and make sure that all services are in their quiescent state after that which means valid descriptors, all needed circuits opened and latest descriptors have been uploaded. For now, only v2 is supported and placeholders for v3 actions for that main loop callback. Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/or/hs_service.c')
-rw-r--r--src/or/hs_service.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/or/hs_service.c b/src/or/hs_service.c
index 5fde42ddbb..a890389cad 100644
--- a/src/or/hs_service.c
+++ b/src/or/hs_service.c
@@ -11,6 +11,7 @@
#include "or.h"
#include "circuitlist.h"
#include "config.h"
+#include "nodelist.h"
#include "relay.h"
#include "rendservice.h"
#include "router.h"
@@ -24,6 +25,15 @@
#include "hs/cell_establish_intro.h"
#include "hs/cell_common.h"
+/* Helper macro. Iterate over every service in the global map. The var is the
+ * name of the service pointer. */
+#define FOR_EACH_SERVICE_BEGIN(var) \
+ STMT_BEGIN \
+ hs_service_t **var##_iter, *var; \
+ HT_FOREACH(var##_iter, hs_service_ht, hs_service_map) { \
+ var = *var##_iter;
+#define FOR_EACH_SERVICE_END } STMT_END ;
+
/* Onion service directory file names. */
static const char *fname_keyfile_prefix = "hs_ed25519";
static const char *fname_hostname = "hostname";
@@ -510,6 +520,78 @@ load_service_keys(hs_service_t *service)
return ret;
}
+/* Scheduled event run from the main loop. Make sure all our services are up
+ * to date and ready for the other scheduled events. This includes looking at
+ * the introduction points status and descriptor rotation time. */
+static void
+run_housekeeping_event(time_t now)
+{
+ (void) now;
+}
+
+/* Scheduled event run from the main loop. Make sure all descriptors are up to
+ * date. Once this returns, each service descriptor needs to be considered for
+ * new introduction circuits and then for upload. */
+static void
+run_build_descriptor_event(time_t now)
+{
+ (void) now;
+ /* For v2 services, this step happens in the upload event. */
+
+ /* Run v3+ events. */
+ FOR_EACH_SERVICE_BEGIN(service) {
+ /* XXX: Actually build descriptors. */
+ (void) service;
+ } FOR_EACH_SERVICE_END;
+}
+
+/* Scheduled event run from the main loop. Make sure we have all the circuits
+ * we need for each service. */
+static void
+run_build_circuit_event(time_t now)
+{
+ (void) now;
+
+ /* Make sure we can actually have enough information to build internal
+ * circuits as required by services. */
+ if (router_have_consensus_path() == CONSENSUS_PATH_UNKNOWN) {
+ return;
+ }
+
+ /* Run v2 check. */
+ if (num_rend_services() > 0) {
+ rend_consider_services_intro_points();
+ }
+ /* Run v3+ check. */
+ FOR_EACH_SERVICE_BEGIN(service) {
+ /* XXX: Check every service for validity of circuits. */
+ (void) service;
+ } FOR_EACH_SERVICE_END;
+}
+
+/* Scheduled event run from the main loop. Try to upload the descriptor for
+ * each service. */
+static void
+run_upload_descriptor_event(time_t now)
+{
+ /* v2 services use the same function for descriptor creation and upload so
+ * we do everything here because the intro circuits were checked before. */
+ if (num_rend_services() > 0) {
+ rend_consider_services_upload(now);
+ rend_consider_descriptor_republication();
+ }
+
+ /* Run v3+ check. */
+ FOR_EACH_SERVICE_BEGIN(service) {
+ /* XXX: Upload if needed the descriptor(s). Update next upload time. */
+ (void) service;
+ } FOR_EACH_SERVICE_END;
+}
+
+/* ========== */
+/* Public API */
+/* ========== */
+
/* Load and/or generate keys for all onion services including the client
* authorization if any. Return 0 on success, -1 on failure. */
int
@@ -619,6 +701,29 @@ hs_service_free(hs_service_t *service)
tor_free(service);
}
+/* Periodic callback. Entry point from the main loop to the HS service
+ * subsystem. This is call every second. This is skipped if tor can't build a
+ * circuit or the network is disabled. */
+void
+hs_service_run_scheduled_events(time_t now)
+{
+ /* First thing we'll do here is to make sure our services are in a
+ * quiescent state for the scheduled events. */
+ run_housekeeping_event(now);
+
+ /* Order matters here. We first make sure the descriptor object for each
+ * service contains the latest data. Once done, we check if we need to open
+ * new introduction circuit. Finally, we try to upload the descriptor for
+ * each service. */
+
+ /* Make sure descriptors are up to date. */
+ run_build_descriptor_event(now);
+ /* Make sure services have enough circuits. */
+ run_build_circuit_event(now);
+ /* Upload the descriptors if needed/possible. */
+ run_upload_descriptor_event(now);
+}
+
/* Initialize the service HS subsystem. */
void
hs_service_init(void)