mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 02:39:05 +01:00
Patched tor and jtorctl for improved hidden service performance.
Two changes have been made to Tor: 1. Set can_complete_circuit to false when the network is disabled, and don't try to build introduction circuits while can_complete_circuit is false. This avoids a situation where Tor tries to build introduction circuits as soon as the network is re-enabled, all the circuits fail, and then Tor waits 5 minutes before trying to build more. 2. Added a FORGETHS command to the control protocol which clears any cached client state relating to a specified hidden service. This can be used to flush state that's likely to be stale before trying to connect to a hidden service with an unstable network connection. Support for the FORGETHS command was also added to jtorctl.
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -525,6 +525,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
}
|
||||
try {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Connecting to " + onion);
|
||||
controlConnection.forgetHiddenService(onion.substring(0, 16));
|
||||
Socks5Proxy proxy = new Socks5Proxy("127.0.0.1", SOCKS_PORT);
|
||||
proxy.resolveAddrLocally(false);
|
||||
Socket s = new SocksSocket(proxy, onion, 80);
|
||||
@@ -546,7 +547,6 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
}
|
||||
|
||||
public void circuitStatus(String status, String id, String path) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Circuit " + id + " " + status);
|
||||
if(status.equals("BUILT") && !circuitBuilt.getAndSet(true)) {
|
||||
LOG.info("First circuit built");
|
||||
if(isRunning()) callback.pollNow();
|
||||
@@ -571,9 +571,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public void unrecognized(String type, String msg) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info(type + " " + msg);
|
||||
}
|
||||
public void unrecognized(String type, String msg) {}
|
||||
|
||||
private static class WriteObserver extends FileObserver {
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
diff -Bbur jtorctl/net/freehaven/tor/control/TorControlConnection.java jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java
|
||||
--- jtorctl/net/freehaven/tor/control/TorControlConnection.java 2014-10-03 12:21:51.883098440 +0100
|
||||
+++ jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java 2014-10-03 12:17:07.429687913 +0100
|
||||
@@ -728,5 +728,12 @@
|
||||
+++ jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java 2014-10-06 16:28:53.516851714 +0100
|
||||
@@ -728,5 +728,19 @@
|
||||
sendAndWaitForResponse("CLOSECIRCUIT "+circID+
|
||||
(ifUnused?" IFUNUSED":"")+"\r\n", null);
|
||||
}
|
||||
@@ -11,6 +11,13 @@ diff -Bbur jtorctl/net/freehaven/tor/control/TorControlConnection.java jtorctl-b
|
||||
+ */
|
||||
+ public void takeOwnership() throws IOException {
|
||||
+ sendAndWaitForResponse("TAKEOWNERSHIP\r\n", null);
|
||||
+ }
|
||||
+
|
||||
+ /** Tells Tor to forget any cached client state relating to the hidden
|
||||
+ * service with the given hostname (excluding the .onion extension).
|
||||
+ */
|
||||
+ public void forgetHiddenService(String hostname) throws IOException {
|
||||
+ sendAndWaitForResponse("FORGETHS " + hostname + "\r\n", null);
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
194
tor.patch
Normal file
194
tor.patch
Normal file
@@ -0,0 +1,194 @@
|
||||
diff --git a/src/or/config.c b/src/or/config.c
|
||||
index 919dd27..c2d3caf 100644
|
||||
--- a/src/or/config.c
|
||||
+++ b/src/or/config.c
|
||||
@@ -1039,6 +1039,8 @@ options_act_reversible(const or_options_t *old_options, char **msg)
|
||||
"non-control network connections. Shutting down all existing "
|
||||
"connections.");
|
||||
connection_mark_all_noncontrol_connections();
|
||||
+ /* We can't complete circuits until the network is re-enabled. */
|
||||
+ can_complete_circuit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/or/control.c b/src/or/control.c
|
||||
index ae9dd69..0ead4c1 100644
|
||||
--- a/src/or/control.c
|
||||
+++ b/src/or/control.c
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "nodelist.h"
|
||||
#include "policies.h"
|
||||
#include "reasons.h"
|
||||
+#include "rendclient.h"
|
||||
+#include "rendcommon.h"
|
||||
#include "rephist.h"
|
||||
#include "router.h"
|
||||
#include "routerlist.h"
|
||||
@@ -197,6 +199,8 @@ static int handle_control_resolve(control_connection_t *conn, uint32_t len,
|
||||
static int handle_control_usefeature(control_connection_t *conn,
|
||||
uint32_t len,
|
||||
const char *body);
|
||||
+static int handle_control_forgeths(control_connection_t *conn, uint32_t len,
|
||||
+ const char *body);
|
||||
static int write_stream_target_to_buf(entry_connection_t *conn, char *buf,
|
||||
size_t len);
|
||||
static void orconn_target_get_name(char *buf, size_t len,
|
||||
@@ -3181,6 +3185,33 @@ handle_control_usefeature(control_connection_t *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/** Called when we get a FORGETHS command: parse the hidden service's onion
|
||||
+ * address and purge any cached state related to the service. */
|
||||
+static int
|
||||
+handle_control_forgeths(control_connection_t *conn, uint32_t len,
|
||||
+ const char *body)
|
||||
+{
|
||||
+ smartlist_t *args;
|
||||
+ char *onion_address;
|
||||
+
|
||||
+ args = getargs_helper("FORGETHS", conn, body, 1, 1);
|
||||
+ if (!args)
|
||||
+ return -1;
|
||||
+ onion_address = smartlist_get(args, 0);
|
||||
+ smartlist_free(args);
|
||||
+
|
||||
+ if (!rend_valid_service_id(onion_address)) {
|
||||
+ connection_write_str_to_buf("513 Invalid hidden service address\r\n", conn);
|
||||
+ tor_free(onion_address);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ rend_client_purge_hidden_service(onion_address);
|
||||
+ tor_free(onion_address);
|
||||
+ send_control_done(conn);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/** Called when <b>conn</b> has no more bytes left on its outbuf. */
|
||||
int
|
||||
connection_control_finished_flushing(control_connection_t *conn)
|
||||
@@ -3480,6 +3511,9 @@ connection_control_process_inbuf(control_connection_t *conn)
|
||||
} else if (!strcasecmp(conn->incoming_cmd, "AUTHCHALLENGE")) {
|
||||
if (handle_control_authchallenge(conn, cmd_data_len, args))
|
||||
return -1;
|
||||
+ } else if (!strcasecmp(conn->incoming_cmd, "FORGETHS")) {
|
||||
+ if (handle_control_forgeths(conn, cmd_data_len, args))
|
||||
+ return -1;
|
||||
} else {
|
||||
connection_printf_to_buf(conn, "510 Unrecognized command \"%s\"\r\n",
|
||||
conn->incoming_cmd);
|
||||
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
|
||||
index 7abbfd6..e550b65 100644
|
||||
--- a/src/or/rendclient.c
|
||||
+++ b/src/or/rendclient.c
|
||||
@@ -29,6 +29,8 @@
|
||||
static extend_info_t *rend_client_get_random_intro_impl(
|
||||
const rend_cache_entry_t *rend_query,
|
||||
const int strict, const int warnings);
|
||||
+static void purge_hid_serv_from_last_hid_serv_requests(
|
||||
+ const char *onion_address);
|
||||
|
||||
/** Purge all potentially remotely-detectable state held in the hidden
|
||||
* service client code. Called on SIGNAL NEWNYM. */
|
||||
@@ -40,6 +42,16 @@ rend_client_purge_state(void)
|
||||
rend_client_purge_last_hid_serv_requests();
|
||||
}
|
||||
|
||||
+/** Purge all cached state relating to the given hidden service. */
|
||||
+void
|
||||
+rend_client_purge_hidden_service(const char *onion_address)
|
||||
+{
|
||||
+ tor_assert(rend_valid_service_id(onion_address));
|
||||
+
|
||||
+ rend_cache_remove_entry(onion_address);
|
||||
+ purge_hid_serv_from_last_hid_serv_requests(onion_address);
|
||||
+}
|
||||
+
|
||||
/** Called when we've established a circuit to an introduction point:
|
||||
* send the introduction request. */
|
||||
void
|
||||
diff --git a/src/or/rendclient.h b/src/or/rendclient.h
|
||||
index 1f731d0..7084aef 100644
|
||||
--- a/src/or/rendclient.h
|
||||
+++ b/src/or/rendclient.h
|
||||
@@ -13,6 +13,7 @@
|
||||
#define TOR_RENDCLIENT_H
|
||||
|
||||
void rend_client_purge_state(void);
|
||||
+void rend_client_purge_hidden_service(const char *onion_address);
|
||||
|
||||
void rend_client_introcirc_has_opened(origin_circuit_t *circ);
|
||||
void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
|
||||
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
|
||||
index d1b4941..3deb5fc 100644
|
||||
--- a/src/or/rendcommon.c
|
||||
+++ b/src/or/rendcommon.c
|
||||
@@ -954,6 +954,34 @@ rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/** Remove any cached descriptors for <b>service_id/b>. */
|
||||
+void
|
||||
+rend_cache_remove_entry(const char *service_id)
|
||||
+{
|
||||
+ char key[REND_SERVICE_ID_LEN_BASE32+2]; /* <version><service_id>\0 */
|
||||
+ rend_cache_entry_t *removed;
|
||||
+
|
||||
+ tor_assert(rend_valid_service_id(service_id));
|
||||
+ if (!rend_cache)
|
||||
+ return;
|
||||
+
|
||||
+ tor_snprintf(key, sizeof(key), "2%s", service_id);
|
||||
+ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key);
|
||||
+ if (removed) {
|
||||
+ log_info(LD_REND, "Removed cached v2 descriptor for service %s.",
|
||||
+ safe_str_client(service_id));
|
||||
+ rend_cache_entry_free(removed);
|
||||
+ }
|
||||
+
|
||||
+ tor_snprintf(key, sizeof(key), "0%s", service_id);
|
||||
+ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key);
|
||||
+ if (removed) {
|
||||
+ log_info(LD_REND, "Removed cached v0 descriptor for service %s.",
|
||||
+ safe_str_client(service_id));
|
||||
+ rend_cache_entry_free(removed);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/** <b>query</b> is a base32'ed service id. If it's malformed, return -1.
|
||||
* Else look it up.
|
||||
* - If it is found, point *desc to it, and write its length into
|
||||
diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h
|
||||
index f476593..331784f 100644
|
||||
--- a/src/or/rendcommon.h
|
||||
+++ b/src/or/rendcommon.h
|
||||
@@ -43,6 +43,7 @@ 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);
|
||||
+void rend_cache_remove_entry(const char *service_id);
|
||||
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,
|
||||
const char *service_id);
|
||||
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
|
||||
index 8a4a11e..35f5e18 100644
|
||||
--- a/src/or/rendservice.c
|
||||
+++ b/src/or/rendservice.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "circuituse.h"
|
||||
#include "config.h"
|
||||
#include "directory.h"
|
||||
+#include "main.h"
|
||||
#include "networkstatus.h"
|
||||
#include "nodelist.h"
|
||||
#include "rendclient.h"
|
||||
@@ -3024,6 +3025,9 @@ rend_services_introduce(void)
|
||||
time_t now;
|
||||
const or_options_t *options = get_options();
|
||||
|
||||
+ if (!can_complete_circuit)
|
||||
+ return;
|
||||
+
|
||||
intro_nodes = smartlist_new();
|
||||
now = time(NULL);
|
||||
|
||||
Reference in New Issue
Block a user