On Tue, Nov 27, 2012 at 12:49 AM, Roger Dingledine arma@mit.edu wrote:
On Sun, Nov 25, 2012 at 07:54:51PM -0500, Nick Mathewson wrote:
[tl;dr: We should make client-side DNS cacheing off by default.]
Be careful -- we seem to rely on the client-side dns cache to let us move on to a new circuit if the current circuit's exit policy doesn't like the stream.
See in connection_ap_process_end_not_open() when we get an END cell of reason END_STREAM_REASON_EXITPOLICY. In that case we remember the mapping between the hostname we sent and the IP address we got back in the END cell: client_dns_set_addressmap(circ, conn->socks_request->address, &addr, conn->chosen_exit_name, ttl); and then when we call /* rewrite it to an IP if we learned one. */ if (addressmap_rewrite(conn->socks_request->address, sizeof(conn->socks_request->address), NULL, NULL)) { it gets rewritten to the IP address so we'll avoid this circuit when we call connection_ap_detach_retriable(). If the rewrite doesn't look at the cache, then we'll just try this circuit once more.
I think the right answer in this case is not to touch the cache at all, but rather to update conn->socks_request->address, setting it to match addr. Using the cache for this is quite roundabout and silly IMO. I'll add a commit to this effect on my branch.
[...]
While I was looking at this design, I thought of a cool attack on 0.2.3 users:
[...]
The bandaid fix is that we should reset node->rejects_all in nodelist_set_consensus() just like we reset is_valid, is_running, etc from the consensus.
Agreed. As another bandaid, we could give same-IP addresses an exception -- but that wouldn't work for any other interesting exit policies.
The better fix is that we need to either make clients have an accurate view of the relay's exit policy (is that ticket 1774?),
I don't know if it's 1774, since we really don't have a great answer for 1774 other than "we should redesign exit policies." That's not going to happen for 0.2.3, though, and it's doesn't seem likely for 0.2.4 at this point.
or we need to stop behaving so drastically when we only know a microdescriptor for the relay and it declines to exit to an address that its short policy looks like it should accept.
I think that's plausible but vague. There are lots of things under the heading of "less drastic".
At the very least, we need to ensure that this particular stream isn't attached to this circuit again. That wouldn't necessarily be so hard. There are probably even backportable versions of that we could try.