[tor-commits] [tor/master] prop224: Directory function to upload descriptor

nickm at torproject.org nickm at torproject.org
Wed Aug 9 00:36:37 UTC 2017


commit bce0c6caadaf27b857f6980f1453798909625267
Author: David Goulet <dgoulet at torproject.org>
Date:   Wed Apr 19 14:36:53 2017 -0400

    prop224: Directory function to upload descriptor
    
    This commit adds a directory command function to make an upload directory
    request for a service descriptor.
    
    It is not used yet, just the groundwork.
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/directory.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/or/directory.h |  4 +++
 src/or/or.h        | 11 +++++--
 3 files changed, 103 insertions(+), 6 deletions(-)

diff --git a/src/or/directory.c b/src/or/directory.c
index 13daea354..fc83c013c 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -186,6 +186,8 @@ purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
     case DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2:
     case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
     case DIR_PURPOSE_FETCH_RENDDESC_V2:
+    case DIR_PURPOSE_FETCH_HSDESC:
+    case DIR_PURPOSE_UPLOAD_HSDESC:
       return 1;
     case DIR_PURPOSE_SERVER:
     default:
@@ -244,6 +246,10 @@ dir_conn_purpose_to_string(int purpose)
       return "hidden-service v2 descriptor fetch";
     case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
       return "hidden-service v2 descriptor upload";
+    case DIR_PURPOSE_FETCH_HSDESC:
+      return "hidden-service descriptor fetch";
+    case DIR_PURPOSE_UPLOAD_HSDESC:
+      return "hidden-service descriptor upload";
     case DIR_PURPOSE_FETCH_MICRODESC:
       return "microdescriptor fetch";
     }
@@ -1034,11 +1040,12 @@ struct directory_request_t {
   size_t payload_len;
   /** Value to send in an if-modified-since header, or 0 for none. */
   time_t if_modified_since;
-  /** Hidden-service-specific information */
+  /** Hidden-service-specific information v2. */
   const rend_data_t *rend_query;
   /** Extra headers to append to the request */
   config_line_t *additional_headers;
-  /** */
+  /** Hidden-service-specific information for v3+. */
+  const hs_ident_dir_conn_t *hs_ident;
   /** Used internally to directory.c: gets informed when the attempt to
    * connect to the directory succeeds or fails, if that attempt bears on the
    * directory's usability as a directory guard. */
@@ -1268,6 +1275,21 @@ directory_request_set_rend_query(directory_request_t *req,
   }
   req->rend_query = query;
 }
+/**
+ * Set an object containing HS connection identifier to be associated with
+ * this request. Note that only an alias to <b>ident</b> is stored, so the
+ * <b>ident</b> object must outlive the request.
+ */
+void
+directory_request_set_hs_ident(directory_request_t *req,
+                               const hs_ident_dir_conn_t *ident)
+{
+  if (ident) {
+    tor_assert(req->dir_purpose == DIR_PURPOSE_FETCH_HSDESC ||
+               req->dir_purpose == DIR_PURPOSE_UPLOAD_HSDESC);
+  }
+  req->hs_ident = ident;
+}
 /** Set a static circuit_guard_state_t object to affliate with the request in
  * <b>req</b>.  This object will receive notification when the attempt to
  * connect to the guard either succeeds or fails. */
@@ -1389,6 +1411,7 @@ directory_initiate_request,(directory_request_t *request))
   const dir_indirection_t indirection = request->indirection;
   const char *resource = request->resource;
   const rend_data_t *rend_query = request->rend_query;
+  const hs_ident_dir_conn_t *hs_ident = request->hs_ident;
   circuit_guard_state_t *guard_state = request->guard_state;
 
   tor_assert(or_addr_port->port || dir_addr_port->port);
@@ -1476,8 +1499,16 @@ directory_initiate_request,(directory_request_t *request))
   conn->dirconn_direct = !anonymized_connection;
 
   /* copy rendezvous data, if any */
-  if (rend_query)
+  if (rend_query) {
+    /* We can't have both v2 and v3+ identifier. */
+    tor_assert_nonfatal(!hs_ident);
     conn->rend_data = rend_data_dup(rend_query);
+  }
+  if (hs_ident) {
+    /* We can't have both v2 and v3+ identifier. */
+    tor_assert_nonfatal(!rend_query);
+    conn->hs_ident = hs_ident_dir_conn_dup(hs_ident);
+  }
 
   if (!anonymized_connection && !use_begindir) {
     /* then we want to connect to dirport directly */
@@ -1835,6 +1866,12 @@ directory_send_command(dir_connection_t *conn,
       httpcommand = "POST";
       url = tor_strdup("/tor/rendezvous2/publish");
       break;
+    case DIR_PURPOSE_UPLOAD_HSDESC:
+      tor_assert(resource);
+      tor_assert(payload);
+      httpcommand = "POST";
+      tor_asprintf(&url, "/tor/hs/%s/publish", resource);
+      break;
     default:
       tor_assert(0);
       return;
@@ -2189,6 +2226,8 @@ static int handle_response_fetch_renddesc_v2(dir_connection_t *,
                                              const response_handler_args_t *);
 static int handle_response_upload_renddesc_v2(dir_connection_t *,
                                               const response_handler_args_t *);
+static int handle_response_upload_hsdesc(dir_connection_t *,
+                                         const response_handler_args_t *);
 
 static int
 dir_client_decompress_response_body(char **bodyp, size_t *bodylenp,
@@ -2489,6 +2528,9 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
     case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
       rv = handle_response_upload_renddesc_v2(conn, &args);
       break;
+    case DIR_PURPOSE_UPLOAD_HSDESC:
+      rv = handle_response_upload_hsdesc(conn, &args);
+      break;
     default:
       tor_assert_nonfatal_unreached();
       rv = -1;
@@ -3180,6 +3222,52 @@ handle_response_upload_renddesc_v2(dir_connection_t *conn,
   return 0;
 }
 
+/**
+ * Handler function: processes a response to a POST request to upload an
+ * hidden service descriptor.
+ **/
+static int
+handle_response_upload_hsdesc(dir_connection_t *conn,
+                              const response_handler_args_t *args)
+{
+  const int status_code = args->status_code;
+  const char *reason = args->reason;
+
+  tor_assert(conn);
+  tor_assert(conn->base_.purpose == DIR_PURPOSE_UPLOAD_HSDESC);
+
+  log_info(LD_REND, "Uploaded hidden service descriptor (status %d "
+                    "(%s))",
+           status_code, escaped(reason));
+  /* For this directory response, it MUST have an hidden service identifier on
+   * this connection. */
+  tor_assert(conn->hs_ident);
+  switch (status_code) {
+  case 200:
+    log_info(LD_REND, "Uploading hidden service descriptor: "
+                      "finished with status 200 (%s)", escaped(reason));
+    /* XXX: Trigger control event. */
+    break;
+  case 400:
+    log_warn(LD_REND, "Uploading hidden service descriptor: http "
+                      "status 400 (%s) response from dirserver "
+                      "'%s:%d'. Malformed hidden service descriptor?",
+             escaped(reason), conn->base_.address, conn->base_.port);
+    /* XXX: Trigger control event. */
+    break;
+  default:
+    log_warn(LD_REND, "Uploading hidden service descriptor: http "
+                      "status %d (%s) response unexpected (server "
+                      "'%s:%d').",
+             status_code, escaped(reason), conn->base_.address,
+             conn->base_.port);
+    /* XXX: Trigger control event. */
+    break;
+  }
+
+  return 0;
+}
+
 /** Called when a directory connection reaches EOF. */
 int
 connection_dir_reached_eof(dir_connection_t *conn)
diff --git a/src/or/directory.h b/src/or/directory.h
index 3e574cc6a..6b3102bc3 100644
--- a/src/or/directory.h
+++ b/src/or/directory.h
@@ -12,6 +12,8 @@
 #ifndef TOR_DIRECTORY_H
 #define TOR_DIRECTORY_H
 
+#include "hs_ident.h"
+
 int directories_have_accepted_server_descriptor(void);
 void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
                                   dirinfo_type_t type, const char *payload,
@@ -71,6 +73,8 @@ void directory_request_set_if_modified_since(directory_request_t *req,
                                              time_t if_modified_since);
 void directory_request_set_rend_query(directory_request_t *req,
                                       const rend_data_t *query);
+void directory_request_set_hs_ident(directory_request_t *req,
+                                    const hs_ident_dir_conn_t *ident);
 
 void directory_request_set_routerstatus(directory_request_t *req,
                                         const routerstatus_t *rs);
diff --git a/src/or/or.h b/src/or/or.h
index a06c816e8..09e58b7b1 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -421,15 +421,20 @@ typedef enum {
 #define DIR_PURPOSE_FETCH_RENDDESC_V2 18
 /** A connection to a directory server: download a microdescriptor. */
 #define DIR_PURPOSE_FETCH_MICRODESC 19
-#define DIR_PURPOSE_MAX_ 19
+/** A connetion to a hidden service directory: upload a descriptor. */
+#define DIR_PURPOSE_UPLOAD_HSDESC 20
+/** A connetion to a hidden service directory: fetch a descriptor. */
+#define DIR_PURPOSE_FETCH_HSDESC 21
+#define DIR_PURPOSE_MAX_ 21
 
 /** True iff <b>p</b> is a purpose corresponding to uploading
  * data to a directory server. */
 #define DIR_PURPOSE_IS_UPLOAD(p)                \
   ((p)==DIR_PURPOSE_UPLOAD_DIR ||               \
    (p)==DIR_PURPOSE_UPLOAD_VOTE ||              \
-   (p)==DIR_PURPOSE_UPLOAD_SIGNATURES || \
-   (p)==DIR_PURPOSE_UPLOAD_RENDDESC_V2)
+   (p)==DIR_PURPOSE_UPLOAD_SIGNATURES ||        \
+   (p)==DIR_PURPOSE_UPLOAD_RENDDESC_V2 ||       \
+   (p)==DIR_PURPOSE_UPLOAD_HSDESC)
 
 #define EXIT_PURPOSE_MIN_ 1
 /** This exit stream wants to do an ordinary connect. */





More information about the tor-commits mailing list