Opened 7 years ago

Last modified 3 years ago

#11360 new enhancement

Listen on IPv6 by default for SocksPort *:Port

Reported by: dgoulet Owned by:
Priority: Medium Milestone: Tor: unspecified
Component: Core Tor/Tor Version:
Severity: Normal Keywords: tor-client, ipv6, torrc, ui, intro
Cc: ln5 Actual Points:
Parent ID: #17811 Points:
Reviewer: Sponsor:


That would be very useful if tor could listen on both IPv4 and IPv6 for the SocksPort. One use case is for Torsocks to work seamlessly with v4 and v6 without having to configure a v6 port in the configuration file and restart the daemon.

One way to fix that would be to change the function parse_port_config() in src/or/config.c to allow multiple default values adding v6 defaults (which would benefit other ports as well).

Else, having a check somewhere that adds other defaults for specific ports but not sure that it's a good idea nor makes sense in the long run in terms of maintainability.

I thought also about bringing back #4760 by default and setting the ipv6 only option only and only if the user has defined an option in the torrc explicitly. For instance, this in the torrc would ONLY allow v6 (remove dual stack).

SocksPort [::1]:9050


Child Tickets

Change History (17)

comment:1 Changed 7 years ago by nickm

Keywords: tor-client added
Milestone: Tor: 0.2.???

Can you specify a little more what you want? Is this just a matter of having "SocksPort *:9050" or "SocksPort 9050" cause Tor to open two SocksPorts if possible, or do the two SocksPorts need to behave differently from each other?

comment:2 Changed 7 years ago by dgoulet

Same behavior here meaning I just want tor to listen on both v4 and v6 for the SocksPort so I guess that would be a matter of "SocksPort *:9050" (or 9050 alone) to open two ports.

The main use case I have is that for torsocks, we establish a socket to the SocksPort and sends it back to the application thus from that point on the app. can use it for any I/O ops. However, for IPv6, this means that the connection to the SocksPort *must* be a v6 family socket (AF_INET6) because that's what we are sending back to the application.

comment:3 Changed 7 years ago by nickm

Ok. Will it be a problem that the address family that is used for the connection from the app to the socksport will not necessarily match the true address family of the destination address? eg you can make a connection to either over an AF_INET or an AF_INET6 socksport, and you won't know whether it will go to an IPv4 or an IPv6 address unless you know what the real address for is.

If that isn't a problem, this wouldn't be so hard to do. I can't think of any showstopper issues, but of course changing the default configuration always poses some risk

comment:4 Changed 7 years ago by dgoulet

Exactly. The address family of the requested socket of the application MUST match the one to the SocksPort or else we end up in a world of complexity to support "app->inet6-->torsocks-->inet-->tor".

I would like to help by providing a patch here but not sure what's the best approach here so please let me know what would be the ideal approach. Thanks!

comment:5 Changed 7 years ago by nickm

So, the trickiest part here is that right now the code assumes 1:1 correspondence between *Port lines in the configuration file and port_cfg_t entries; and it also assumes a 1:(0,1) correspondence between port_cfg_t entries as created by parse_port_config(), and listener connections as opened in retry_listener_ports(). One of those correspondences would need to get relaxed to be 1:many, but I'm not sure which. It would be cleaner to do the latter, if practical.

To start out, have a look at the port_cfg_t structure, how retry_listener_ports() reconciles a port_cfg_t list with a list of listener connections, and at how parse_port_config() generates port_cfg_t.

comment:6 Changed 7 years ago by dgoulet

Oh I already looked at all of this for a clean solution :).

I'll follow your recommendation and try to come up with something that we can at that point evaluate if it's the right way to go.

comment:7 Changed 5 years ago by teor

Keywords: ipv6 added
Parent ID: #17811
Severity: Normal

comment:8 Changed 5 years ago by teor

Owner: set to teor
Status: newassigned

To summarise, I think we need to implement the following changes (like #17901):

  • For every *Port that currently listens on by default:
    • ControlPort TransPort/NATDPort DNSPort ExtORPort SocksPort
  • Bind all *Ports to:
    • IPv4 localhost as described in #17901
    • As long as there is an IPv4 localhost
  • Open another *Port listener on the same port on [::1]:
    • As long as there is no conflicting listener explicitly configured on [::1] or [::]
    • This relies on the IPV6_V6ONLY fix in #4760 to work without port conflicts
  • Since we've created up to two listeners for each configured *Port, make sure:
    • Listener shutdown closes both listeners, and
    • Any code that uses port_cfg_t doesn't rely on localhost being, or local ports being on, or there being exactly one listener per port_cfg_t.

This change makes IPv6-only configurations work, and allows programs to connect to tor over IPv6 localhost in the default tor configuration.

This issue also affects HiddenServicePort, which defaults to connecting to This won't work on an IPv6-only system. We should add instructions to the failure warning to specify HiddenServicePort <VirtPort> [::1]:<TargetPort> for IPv6-only hidden services. (I think it's OK to require operators to do this explicitly, rather than unexpectedly connecting to a service bound to IPv6 localhost.)

comment:9 Changed 5 years ago by teor

Oh, and change the warning condition in #17901 to:

  • If there is no or [::1] on the server, reject the *Port with a warning that tells the user to supply an explicit IP address if they really want their *Port listening on a non-local address.

comment:10 Changed 5 years ago by teor

I've split off #17948 to fix the IPv4/IPv6 localhost issue for hidden service ports.

comment:11 Changed 5 years ago by teor

Owner: teor deleted

I don't think I'll get this done in 0.2.8, but I'm happy to review it if someone else gets in done.

Until then, a workaround is:

SOCKSPort 9050
SOCKSPort [::1] 9050

comment:12 Changed 5 years ago by teor

One way to implement this change:

  • In parse_ports, pass a default IPv4 and IPv6 address to parse_port_config
    • Either or both addresses can be NULL (meaning "no listener for this family")
  • In parse_port_config, create a port for IPv4 and IPv6
    • don't add IPv6 if there's a matching IPv6 in the port list
    • don't add IPv6 if IPv4 is and binds to IPv6 as well
    • maybe don't add IPv4 if IPv6 is :: and :: binds to IPv4 as well, alternately, just pass and NULL to parse_port_config to avoid this issue
  • make logging of "protocol not supported" on non-IPv6 systems quieter
  • maybe add new options DefaultLoopbackListenerUseIPv4/6 to allow listeners to be turned on or off for IPv4/6 in the torrc
    • this avoids changing behaviour of existing configs, which I think is the right way to do it

comment:13 Changed 4 years ago by teor

Milestone: Tor: 0.2.???Tor: 0.3.???

Milestone renamed

comment:14 Changed 4 years ago by nickm

Keywords: tor-03-unspecified-201612 added
Milestone: Tor: 0.3.???Tor: unspecified

Finally admitting that 0.3.??? was a euphemism for Tor: unspecified all along.

comment:15 Changed 3 years ago by nickm

Keywords: tor-03-unspecified-201612 removed

Remove an old triaging keyword.

comment:16 Changed 3 years ago by nickm

Status: assignednew

Change the status of all assigned/accepted Tor tickets with owner="" to "new".

comment:17 Changed 3 years ago by nickm

Keywords: torrc ui intro added
Summary: Listen on IPv6 by default for SocksPortListen on IPv6 by default for SocksPort *:Port
Note: See TracTickets for help on using tickets.