A managed proxy can announce that it is listening on an IPv6 address:
VERSION 1SMETHOD dummy [::]:10000SMETHODS DONE
tor caches the address in ~/.tor/state without brackets around the IPv6 address:
Oct 02 03:18:30.000 [info] handle_proxy_line(): Got a line from managed proxy '/home/david/branches/tor/dummy.sh': (VERSION 1)Oct 02 03:18:30.000 [info] handle_proxy_line(): Got a line from managed proxy '/home/david/branches/tor/dummy.sh': (SMETHOD dummy [::]:10000)Oct 02 03:18:30.000 [info] parse_smethod_line(): Server transport dummy at [::]:10000.Oct 02 03:18:30.000 [info] handle_proxy_line(): Got a line from managed proxy '/home/david/branches/tor/dummy.sh': (SMETHODS DONE)Oct 02 03:18:30.000 [info] handle_methods_done(): Server managed proxy '/home/david/branches/tor/dummy.sh' configuration completed!Oct 02 03:18:30.000 [info] save_transport_to_state(): It's the first time we see this transport. Let's save its address:portOct 02 03:18:30.000 [notice] Registered server transport 'dummy' at ':::10000'
TransportProxy dummy :::10000
The next time running the transport, tor writes to the environment a TOR_PT_SERVER_BINDADDR without brackets as well.
I started thinking that maybe it would make sense to change the behavior of fmt_addr() so that it does decorate IPv6 addresses by default, but then jeroen in IRC reminded me that bracket decoration is only necessary when ':' is used a separator, and maybe we shouldn't decorate all the addresses.
I think I will proceed with looking at all the pluggable-transport-related code and turning fmt_addr() to fmt_and_decorate_addr() when needed.
I started thinking that maybe it would make sense to change the behavior of fmt_addr() so that it does decorate IPv6 addresses by default, but then jeroen in IRC reminded me that bracket decoration is only necessary when ':' is used a separator, and maybe we shouldn't decorate all the addresses.
Maybe what you want is a new fmt_addr_port or similar that takes both an address and a port number. This would additionally allow factoring out some "%s:%u" and "%s:%d" formats; such specifiers can be taken as hints that decoration is needed.
[PATCH 1/5] decorates all addresses in log messages. This should be uncontroversial as it doesn't affect any network or on-disk format.
[PATCH 2/5] decorates addresses in HTTP CONNECT proxy requests.
[PATCH 3/5] decorates the TransportProxy statefile entry, the subject of this ticket.
[PATCH 4/5] adds a new fmt_addrport function to factor out the common "%s:%d" formatting.
[PATCH 5/5] uses fmt_addrport where appropriate.
There was only one fmt_addr I wasn't sure how to deal with, in pt_get_extra_info_descriptor_string in transports.c:
Maybe review of this patchset would be easier if [PATCH 4/5] did not invalidate the previous patches? I think it would make more sense if the patchset introduced fmt_addrport() right from the beginning and then simply used it.
Also, this patchset makes make check-spaces fail because of wide lines.
David, do you have the time and will to address the above comments or shall I?
I actually like the approach of switching to fmt_addrport(). the fmt_addrport() change is a refactoring, and refactoring commits should not IMO change behavior.
I actually like the approach of switching to fmt_addrport(). the fmt_addrport() change is a refactoring, and refactoring commits should not IMO change behavior.
Oh. Looking at it this way, it's indeed better.
Then I guess the only thing that remains is fixing that check-spaces complaint and rebasing to the new legacy/trac#7014 (moved)?
pt_get_extra_info_descriptor_string needs some attention indeed. Mainly because of the fmt_addr32() that is called.
How about changing:
/* If the transport proxy returned "0.0.0.0" as its address, and * we know our external IP address, use it. Otherwise, use the * returned address. */ const char *addr_str = fmt_addr(&t->addr); uint32_t external_ip_address = 0; if (tor_addr_is_null(&t->addr) && router_pick_published_address(get_options(), &external_ip_address) >= 0) { /* returned addr was 0.0.0.0 and we found our external IP address: use it. */ addr_str = fmt_addr32(external_ip_address); } smartlist_add_asprintf(string_chunks, "transport %s %s:%u", t->name, addr_str, t->port);
to
/* If the transport proxy returned "0.0.0.0" as its address, and * we know our external IP address, use it. Otherwise, use the * returned address. */ const char *addrport = NULL; uint32_t external_ip_address = 0; if (tor_addr_is_null(&t->addr) && router_pick_published_address(get_options(), &external_ip_address) >= 0) { tor_addr_t addr; tor_addr_from_ipv4h(&addr, external_ip_address); addrport = fmt_addrport(&addr, t->port); } else { addrport = fmt_addrport(&t->addr, t->port); } smartlist_add_asprintf(string_chunks, "transport %s %s", t->name, addrport);
BTW, router_pick_published_address() seems to only set 32-bit IP addresses, so using tor_addr_from_ipv4h() should be OK. Why does router_pick_published_address() only work for 32-bit IP addresses?
Aaron, what will happen if bridgedb starts getting IPv6 addresses in the "transport" extra-info lines? So for example instead of "transport bla 7.7.7.7:4444" it will get "transport bla [1234:4444::34]:5555". Is BridgeDB prepared for this occasion?
So what is it doing, is it assuming that the last colon in an address:port string is always a port separator, even when address is IPv6 without brackets? The code in comment:5 would, for example, format the address 1234::5678 and port 9999 as
transport foo 1234::5678:9999
and not
transport foo [1234::5678]:9999
So in other words, is there code somewhere that already expects IPv6 addresses in transport lines not to have brackets, and are we going to break it if we add brackets?
So what is it doing, is it assuming that the last colon in an address:port string is always a port separator, even when address is IPv6 without brackets? The code in comment:5 would, for example, format the address 1234::5678 and port 9999 as
{{{
transport foo 1234::5678:9999
}}}
and not
{{{
transport foo [1234::5678]:9999
}}}
So in other words, is there code somewhere that already expects IPv6 addresses in transport lines not to have brackets, and are we going to break it if we add brackets?
No, I should have clarified. BridgeDB expects IPv6 addresses to be bracketed, just like the "or-address" and "a" lines are. If you -don't- add brackets, BridgeDB will not parse the IP and skip the line.
Great; I merged it into master with7ea904cb. You may want to check the merge to make sure I didn't resolve the conflict incorrectly; it seemed pretty trivial though.
Trac: Resolution: N/Ato fixed Status: needs_review to closed