commit 4b13ebd5ab4d051803e9cfde8bb965a4bf8ea90d
Merge: 0130e7c 8a36f21
Author: Sebastian Hahn <sebastian(a)torproject.org>
Date: Thu Apr 28 19:00:34 2011 +0200
Merge branch 'bug3k_021' into bug3k_022
Conflicts:
src/or/or.h
src/or/rendclient.c
changes/forget-rend-descs-on-newnym | 9 ++++
src/or/circuituse.c | 19 ++++++---
src/or/main.c | 2 +
src/or/rendclient.c | 81 +++++++++++++++++++++++++++-------
src/or/rendclient.h | 1 +
src/or/rendcommon.c | 10 ++++
src/or/rendcommon.h | 1 +
7 files changed, 100 insertions(+), 23 deletions(-)
diff --cc src/or/rendclient.c
index 65e632f,fb95efb..97345bf
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@@ -91,28 -74,67 +91,39 @@@ rend_client_send_introduction(origin_ci
if (rend_cache_lookup_entry(introcirc->rend_data->onion_address, -1,
&entry) < 1) {
- log_warn(LD_REND,
- "query %s didn't have valid rend desc in cache. Failing.",
- escaped_safe_str_client(introcirc->rend_data->onion_address));
- goto err;
+ log_info(LD_REND,
+ "query %s didn't have valid rend desc in cache. "
+ "Refetching descriptor.",
+ safe_str(introcirc->rend_data->onion_address));
- /* Fetch both v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
+ rend_client_refetch_v2_renddesc(introcirc->rend_data);
- if (introcirc->rend_data->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(introcirc->rend_data->onion_address);
+ {
+ connection_t *conn;
+
+ while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
+ AP_CONN_STATE_CIRCUIT_WAIT,
- introcirc->rend_data->onion_address, -1))) {
++ introcirc->rend_data->onion_address))) {
+ conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ }
+ }
+
+ return -1;
}
- /* first 20 bytes of payload are the hash of the intro key */
+ /* first 20 bytes of payload are the hash of Bob's pk */
- if (entry->parsed->version == 0) { /* un-versioned descriptor */
- intro_key = entry->parsed->pk;
- } else { /* versioned descriptor */
- intro_key = NULL;
- SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
- intro, {
- if (!memcmp(introcirc->build_state->chosen_exit->identity_digest,
- intro->extend_info->identity_digest, DIGEST_LEN)) {
- intro_key = intro->intro_key;
- break;
- }
- });
- if (!intro_key) {
- /** XXX This case probably means that the intro point vanished while
- * we were building a circuit to it. In the future, we should find
- * out how that happened and whether we should kill the circuits to
- * removed intro points immediately. See task 1073. */
- int num_intro_points = smartlist_len(entry->parsed->intro_nodes);
- if (rend_cache_lookup_entry(introcirc->rend_data->onion_address,
- 0, &entry) > 0) {
- log_info(LD_REND, "We have both a v0 and a v2 rend desc for this "
- "service. The v2 desc doesn't contain the introduction "
- "point (and key) to send an INTRODUCE1/2 cell to this "
- "introduction point. Assuming the introduction point "
- "is for v0 rend clients and using the service key "
- "from the v0 desc instead. (This is probably a bug, "
- "because we shouldn't even have both a v0 and a v2 "
- "descriptor for the same service.)");
- /* See flyspray task 1024. */
- intro_key = entry->parsed->pk;
- } else {
- log_info(LD_REND, "Internal error: could not find intro key; we "
- "only have a v2 rend desc with %d intro points.",
- num_intro_points);
- goto perm_err;
- }
+ intro_key = NULL;
+ SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
+ intro, {
+ if (!memcmp(introcirc->build_state->chosen_exit->identity_digest,
+ intro->extend_info->identity_digest, DIGEST_LEN)) {
+ intro_key = intro->intro_key;
+ break;
}
+ });
+ if (!intro_key) {
- log_info(LD_REND, "Our introduction point knowledge changed in "
- "mid-connect! Could not find intro key; we only have a "
- "v2 rend desc with %d intro points. Giving up.",
++ log_info(LD_REND, "Internal error: could not find intro key; we "
++ "only have a v2 rend desc with %d intro points.",
+ smartlist_len(entry->parsed->intro_nodes));
- goto err;
++ goto perm_err;
}
if (crypto_pk_get_digest(intro_key, payload)<0) {
log_warn(LD_BUG, "Internal error: couldn't hash public key.");
@@@ -526,8 -574,45 +537,44 @@@ rend_client_refetch_v2_renddesc(const r
return;
}
+ /** Cancel all rendezvous descriptor fetches currently in progress.
+ */
+ void
+ rend_client_cancel_descriptor_fetches(void)
+ {
+ smartlist_t *connection_array = get_connection_array();
+
+ SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) {
+ if (conn->type == CONN_TYPE_DIR &&
+ (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC ||
+ conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2)) {
+ /* It's a rendezvous descriptor fetch in progress -- cancel it
+ * by marking the connection for close.
+ *
+ * Even if this connection has already reached EOF, this is
+ * enough to make sure that if the descriptor hasn't been
+ * processed yet, it won't be. See the end of
+ * connection_handle_read; connection_reached_eof (indirectly)
+ * processes whatever response the connection received. */
+
+ const rend_data_t *rd = (TO_DIR_CONN(conn))->rend_data;
+ if (!rd) {
+ log_warn(LD_BUG | LD_REND,
+ "Marking for close dir conn fetching rendezvous "
+ "descriptor for unknown service!");
+ } else {
- log_debug(LD_REND, "Marking for close dir conn fetching v%d "
++ log_debug(LD_REND, "Marking for close dir conn fetching "
+ "rendezvous descriptor for service %s",
- (int)(rd->rend_desc_version),
+ safe_str(rd->onion_address));
+ }
+ connection_mark_for_close(conn);
+ }
+ } SMARTLIST_FOREACH_END(conn);
+ }
+
/** Remove failed_intro from ent. If ent now has no intro points, or
* service is unrecognized, then launch a new renddesc fetch.
+
*
* Return -1 if error, 0 if no intro points remain or service
* unrecognized, 1 if recognized and some intro points remain.
diff --cc src/or/rendclient.h
index 3f2e58e,0000000..6910c1a
mode 100644,000000..100644
--- a/src/or/rendclient.h
+++ b/src/or/rendclient.h
@@@ -1,44 -1,0 +1,45 @@@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2011, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file rendclient.h
+ * \brief Header file for rendclient.c.
+ **/
+
+#ifndef _TOR_RENDCLIENT_H
+#define _TOR_RENDCLIENT_H
+
+void rend_client_introcirc_has_opened(origin_circuit_t *circ);
+void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
+int rend_client_introduction_acked(origin_circuit_t *circ,
+ const uint8_t *request,
+ size_t request_len);
+void rend_client_refetch_v2_renddesc(const rend_data_t *rend_query);
++void rend_client_cancel_descriptor_fetches(void);
+int rend_client_remove_intro_point(extend_info_t *failed_intro,
+ const rend_data_t *rend_query);
+int rend_client_rendezvous_acked(origin_circuit_t *circ,
+ const uint8_t *request,
+ size_t request_len);
+int rend_client_receive_rendezvous(origin_circuit_t *circ,
+ const uint8_t *request,
+ size_t request_len);
+void rend_client_desc_trynow(const char *query);
+
+extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query);
+int rend_client_any_intro_points_usable(const rend_cache_entry_t *entry);
+
+int rend_client_send_introduction(origin_circuit_t *introcirc,
+ origin_circuit_t *rendcirc);
+int rend_parse_service_authorization(or_options_t *options,
+ int validate_only);
+rend_service_authorization_t *rend_client_lookup_service_authorization(
+ const char *onion_address);
+void rend_service_authorization_free_all(void);
+rend_data_t *rend_data_dup(const rend_data_t *request);
+
+#endif
+
diff --cc src/or/rendcommon.h
index 5014957,0000000..44b5227
mode 100644,000000..100644
--- a/src/or/rendcommon.h
+++ b/src/or/rendcommon.h
@@@ -1,65 -1,0 +1,66 @@@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2011, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file rendcommon.h
+ * \brief Header file for rendcommon.c.
+ **/
+
+#ifndef _TOR_RENDCOMMON_H
+#define _TOR_RENDCOMMON_H
+
+/** Free all storage associated with <b>data</b> */
+static INLINE void
+rend_data_free(rend_data_t *data)
+{
+ tor_free(data);
+}
+
+int rend_cmp_service_ids(const char *one, const char *two);
+
+void rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
+ int command, size_t length,
+ const uint8_t *payload);
+
+void rend_service_descriptor_free(rend_service_descriptor_t *desc);
+rend_service_descriptor_t *rend_parse_service_descriptor(const char *str,
+ size_t len);
+int rend_get_service_id(crypto_pk_env_t *pk, char *out);
+void rend_encoded_v2_service_descriptor_free(
+ rend_encoded_v2_service_descriptor_t *desc);
+void rend_intro_point_free(rend_intro_point_t *intro);
+
+void rend_cache_init(void);
+void rend_cache_clean(void);
+void rend_cache_clean_v2_descs_as_dir(void);
++void rend_cache_purge(void);
+void rend_cache_free_all(void);
+int rend_valid_service_id(const char *query);
+int rend_cache_lookup_desc(const char *query, int version, const char **desc,
+ size_t *desc_len);
+int rend_cache_lookup_entry(const char *query, int version,
+ rend_cache_entry_t **entry_out);
+int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc);
+int rend_cache_store(const char *desc, size_t desc_len, int published);
+int rend_cache_store_v2_desc_as_client(const char *desc,
+ const rend_data_t *rend_query);
+int rend_cache_store_v2_desc_as_dir(const char *desc);
+int rend_cache_size(void);
+int rend_encode_v2_descriptors(smartlist_t *descs_out,
+ rend_service_descriptor_t *desc, time_t now,
+ uint8_t period, rend_auth_type_t auth_type,
+ crypto_pk_env_t *client_key,
+ smartlist_t *client_cookies);
+int rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
+ const char *descriptor_cookie,
+ time_t now, uint8_t replica);
+int rend_id_is_in_interval(const char *a, const char *b, const char *c);
+void rend_get_descriptor_id_bytes(char *descriptor_id_out,
+ const char *service_id,
+ const char *secret_id_part);
+
+#endif
+