|
@@ -1692,8 +1692,37 @@ directory_send_command(dir_connection_t *conn,
|
|
|
tor_assert(resource);
|
|
|
tor_assert(strlen(resource) <= ED25519_BASE64_LEN);
|
|
|
tor_assert(!payload);
|
|
|
+ if (getenv("PIR_CLIENT_PATH")) {
|
|
|
+ HSClientPIRParams *pirparams =
|
|
|
+ hs_client_pirparams_lookup(req->routerstatus->identity_digest);
|
|
|
+ if (!pirparams) {
|
|
|
+ /* First try to get the pironion params if we want them
|
|
|
+ * but don't have them yet. */
|
|
|
+ conn->pirclient_state = PIRCLIENT_STATE_AWAITING_PARAMS;
|
|
|
+ httpcommand = "GET";
|
|
|
+ tor_asprintf(&url, "/tor/pironion/params");
|
|
|
+ log_info(LD_DIR, "PIRCLIENT Fetching params from %s",
|
|
|
+ safe_str_client(routerstatus_describe(req->routerstatus)));
|
|
|
+ break;
|
|
|
+ } else if (pirparams->size > 0) {
|
|
|
+ /* We have the params; privately fetch the resource */
|
|
|
+ /* PIRONION TODO: fill this in, but for now, fetch it not
|
|
|
+ * privately. */
|
|
|
+ // conn->pirclient_state = PIRCLIENT_STATE_AWAITING_PIRREPLY;
|
|
|
+ httpcommand = "GET";
|
|
|
+ tor_asprintf(&url, "/tor/hs/3/%s", resource);
|
|
|
+ log_info(LD_DIR, "PIRCLIENT PIR query (well, not yet) to %s",
|
|
|
+ safe_str_client(routerstatus_describe(req->routerstatus)));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* Just fetch it normally, either because we're not configured to
|
|
|
+ * try PIR at all, or because we asked, and the hsdir didn't reply
|
|
|
+ * with PIR params. */
|
|
|
httpcommand = "GET";
|
|
|
tor_asprintf(&url, "/tor/hs/3/%s", resource);
|
|
|
+ log_info(LD_DIR, "PIRCLIENT non-PIR hs query for %s to %s",
|
|
|
+ resource, safe_str_client(routerstatus_describe(req->routerstatus)));
|
|
|
break;
|
|
|
case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
|
|
|
tor_assert(!resource);
|
|
@@ -1866,6 +1895,12 @@ dir_client_decompress_response_body(char **bodyp, size_t *bodylenp,
|
|
|
|
|
|
int plausible = body_is_plausible(body, body_len, conn->base_.purpose);
|
|
|
|
|
|
+ /* If we're getting PIR stuff back, it'll be binary but not compressed. */
|
|
|
+ if (conn->base_.purpose == DIR_PURPOSE_FETCH_HSDESC &&
|
|
|
+ conn->pirclient_state != PIRCLIENT_STATE_NONE) {
|
|
|
+ plausible = 1;
|
|
|
+ }
|
|
|
+
|
|
|
if (plausible && compression == NO_METHOD) {
|
|
|
return 0;
|
|
|
}
|
|
@@ -2713,12 +2748,61 @@ handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
|
|
|
const char *reason = args->reason;
|
|
|
const char *body = args->body;
|
|
|
const size_t body_len = args->body_len;
|
|
|
+ const node_t *node = node_get_by_id(conn->identity_digest);
|
|
|
+ const routerstatus_t *rstat = NULL;
|
|
|
+ if (node) {
|
|
|
+ rstat = node->rs;
|
|
|
+ }
|
|
|
|
|
|
tor_assert(conn->hs_ident);
|
|
|
|
|
|
log_info(LD_REND,"Received v3 hsdesc (body size %d, status %d (%s))",
|
|
|
(int)body_len, status_code, escaped(reason));
|
|
|
|
|
|
+ /* If we're waiting for PIR parameters, see if we got them. */
|
|
|
+ if (conn->pirclient_state == PIRCLIENT_STATE_AWAITING_PARAMS) {
|
|
|
+ if (status_code == 200 && body_len > 0) {
|
|
|
+ /* Record the PIR params */
|
|
|
+ log_info(LD_REND,"PIRCLIENT received pirparams from %s",
|
|
|
+ safe_str_client(routerstatus_describe(rstat)));
|
|
|
+ hs_client_pirparams_insert(conn->identity_digest, body_len, body);
|
|
|
+ } else {
|
|
|
+ /* Record that we did not receive PIR params when we asked */
|
|
|
+ log_info(LD_REND,"PIRCLIENT failed to receive pirparams from %s",
|
|
|
+ safe_str_client(routerstatus_describe(rstat)));
|
|
|
+ hs_client_pirparams_insert(conn->identity_digest, 0, NULL);
|
|
|
+ }
|
|
|
+ /* Setup and send a new directory request for the same resouce to
|
|
|
+ * the same hsdir; this time, it won't ask for params, but will do a
|
|
|
+ * PIR request (if there are params) or a non-private request (if
|
|
|
+ * not). */
|
|
|
+ if (rstat) {
|
|
|
+ directory_request_t *req =
|
|
|
+ directory_request_new(DIR_PURPOSE_FETCH_HSDESC);
|
|
|
+ directory_request_set_routerstatus(req, rstat);
|
|
|
+ directory_request_set_indirection(req, DIRIND_ANONYMOUS);
|
|
|
+ directory_request_set_resource(req, conn->requested_resource);
|
|
|
+ directory_request_fetch_set_hs_ident(req, conn->hs_ident);
|
|
|
+ log_info(LD_REND, "PIRCLIENT Refetching %s from %s",
|
|
|
+ conn->requested_resource,
|
|
|
+ safe_str_client(routerstatus_describe(req->routerstatus)));
|
|
|
+ directory_initiate_request(req);
|
|
|
+ directory_request_free(req);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If we're waiting for a PIR response, decode it. */
|
|
|
+ if (conn->pirclient_state == PIRCLIENT_STATE_AWAITING_PIRREPLY) {
|
|
|
+ /* PIRONION TODO: Fill this in */
|
|
|
+ log_info(LD_REND,"PIRCLIENT received PIR reply from %s",
|
|
|
+ safe_str_client(routerstatus_describe(rstat)));
|
|
|
+ }
|
|
|
+
|
|
|
+ log_info(LD_REND,"PIRCLIENT received hsdesc from %s",
|
|
|
+ safe_str_client(routerstatus_describe(rstat)));
|
|
|
+
|
|
|
switch (status_code) {
|
|
|
case 200:
|
|
|
/* We got something: Try storing it in the cache. */
|