mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Make option OutboundBindAddress accept IPv6 addresses too.
Implements ticket 6786.
This commit is contained in:
+4
-2
@@ -472,8 +472,10 @@ GENERAL OPTIONS
|
|||||||
**OutboundBindAddress** __IP__::
|
**OutboundBindAddress** __IP__::
|
||||||
Make all outbound connections originate from the IP address specified. This
|
Make all outbound connections originate from the IP address specified. This
|
||||||
is only useful when you have multiple network interfaces, and you want all
|
is only useful when you have multiple network interfaces, and you want all
|
||||||
of Tor's outgoing connections to use a single one. This setting will be
|
of Tor's outgoing connections to use a single one. This option may
|
||||||
ignored for connections to the loopback addresses (127.0.0.0/8 and ::1).
|
be used twice, once with an IPv4 address and once with an IPv6 address.
|
||||||
|
This setting will be ignored for connections to the loopback addresses
|
||||||
|
(127.0.0.0/8 and ::1).
|
||||||
|
|
||||||
**PidFile** __FILE__::
|
**PidFile** __FILE__::
|
||||||
On startup, write our PID to FILE. On clean shutdown, remove
|
On startup, write our PID to FILE. On clean shutdown, remove
|
||||||
|
|||||||
+66
-1
@@ -302,7 +302,7 @@ static config_var_t _option_vars[] = {
|
|||||||
V(NumEntryGuards, UINT, "3"),
|
V(NumEntryGuards, UINT, "3"),
|
||||||
V(ORListenAddress, LINELIST, NULL),
|
V(ORListenAddress, LINELIST, NULL),
|
||||||
VPORT(ORPort, LINELIST, NULL),
|
VPORT(ORPort, LINELIST, NULL),
|
||||||
V(OutboundBindAddress, STRING, NULL),
|
V(OutboundBindAddress, LINELIST, NULL),
|
||||||
|
|
||||||
V(PathBiasCircThreshold, INT, "-1"),
|
V(PathBiasCircThreshold, INT, "-1"),
|
||||||
V(PathBiasNoticeRate, DOUBLE, "-1"),
|
V(PathBiasNoticeRate, DOUBLE, "-1"),
|
||||||
@@ -474,6 +474,8 @@ static int options_init_logs(or_options_t *options, int validate_only);
|
|||||||
|
|
||||||
static void init_libevent(const or_options_t *options);
|
static void init_libevent(const or_options_t *options);
|
||||||
static int opt_streq(const char *s1, const char *s2);
|
static int opt_streq(const char *s1, const char *s2);
|
||||||
|
static int parse_outbound_addresses(or_options_t *options, int validate_only,
|
||||||
|
char **msg);
|
||||||
|
|
||||||
/** Magic value for or_options_t. */
|
/** Magic value for or_options_t. */
|
||||||
#define OR_OPTIONS_MAGIC 9090909
|
#define OR_OPTIONS_MAGIC 9090909
|
||||||
@@ -1390,6 +1392,12 @@ options_act(const or_options_t *old_options)
|
|||||||
tor_free(http_authenticator);
|
tor_free(http_authenticator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parse_outbound_addresses(options, 0, &msg) < 0) {
|
||||||
|
log_warn(LD_BUG, "Failed parsing oubound bind addresses: %s", msg);
|
||||||
|
tor_free(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for transitions that need action. */
|
/* Check for transitions that need action. */
|
||||||
if (old_options) {
|
if (old_options) {
|
||||||
int revise_trackexithosts = 0;
|
int revise_trackexithosts = 0;
|
||||||
@@ -2164,6 +2172,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
if (parse_ports(options, 1, msg, &n_ports) < 0)
|
if (parse_ports(options, 1, msg, &n_ports) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (parse_outbound_addresses(options, 1, msg) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (validate_data_directory(options)<0)
|
if (validate_data_directory(options)<0)
|
||||||
REJECT("Invalid DataDirectory");
|
REJECT("Invalid DataDirectory");
|
||||||
|
|
||||||
@@ -5482,3 +5493,57 @@ getinfo_helper_config(control_connection_t *conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Parse outbound bind address option lines. If <b>validate_only</b>
|
||||||
|
* is not 0 update _OutboundBindAddressIPv4 and
|
||||||
|
* _OutboundBindAddressIPv6 in <b>options</b>. On failure, set
|
||||||
|
* <b>msg</b> (if provided) to a newly allocated string containing a
|
||||||
|
* description of the problem and return -1. */
|
||||||
|
static int
|
||||||
|
parse_outbound_addresses(or_options_t *options, int validate_only, char **msg)
|
||||||
|
{
|
||||||
|
const config_line_t *lines = options->OutboundBindAddress;
|
||||||
|
int found_v4 = 0, found_v6 = 0;
|
||||||
|
|
||||||
|
if (!validate_only) {
|
||||||
|
memset(&options->_OutboundBindAddressIPv4, 0,
|
||||||
|
sizeof(options->_OutboundBindAddressIPv4));
|
||||||
|
memset(&options->_OutboundBindAddressIPv6, 0,
|
||||||
|
sizeof(options->_OutboundBindAddressIPv6));
|
||||||
|
}
|
||||||
|
while (lines) {
|
||||||
|
tor_addr_t addr, *dst_addr = NULL;
|
||||||
|
int af = tor_addr_parse(&addr, lines->value);
|
||||||
|
switch (af) {
|
||||||
|
case AF_INET:
|
||||||
|
if (found_v4) {
|
||||||
|
if (msg)
|
||||||
|
tor_asprintf(msg, "Multiple IPv4 outbound bind addresses "
|
||||||
|
"configured: %s", lines->value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
found_v4 = 1;
|
||||||
|
dst_addr = &options->_OutboundBindAddressIPv4;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
if (found_v6) {
|
||||||
|
if (msg)
|
||||||
|
tor_asprintf(msg, "Multiple IPv6 outbound bind addresses "
|
||||||
|
"configured: %s", lines->value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
found_v6 = 1;
|
||||||
|
dst_addr = &options->_OutboundBindAddressIPv6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (msg)
|
||||||
|
tor_asprintf(msg, "Outbound bind address '%s' didn't parse.",
|
||||||
|
lines->value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!validate_only)
|
||||||
|
tor_addr_copy(dst_addr, &addr);
|
||||||
|
lines = lines->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+28
-17
@@ -1377,23 +1377,34 @@ connection_connect(connection_t *conn, const char *address,
|
|||||||
|
|
||||||
make_socket_reuseable(s);
|
make_socket_reuseable(s);
|
||||||
|
|
||||||
if (options->OutboundBindAddress && !tor_addr_is_loopback(addr)) {
|
if (!tor_addr_is_loopback(addr)) {
|
||||||
struct sockaddr_in ext_addr;
|
const tor_addr_t *ext_addr = NULL;
|
||||||
|
if (protocol_family == AF_INET &&
|
||||||
memset(&ext_addr, 0, sizeof(ext_addr));
|
!tor_addr_is_null(&options->_OutboundBindAddressIPv4))
|
||||||
ext_addr.sin_family = AF_INET;
|
ext_addr = &options->_OutboundBindAddressIPv4;
|
||||||
ext_addr.sin_port = 0;
|
else if (protocol_family == AF_INET6 &&
|
||||||
if (!tor_inet_aton(options->OutboundBindAddress, &ext_addr.sin_addr)) {
|
!tor_addr_is_null(&options->_OutboundBindAddressIPv6))
|
||||||
log_warn(LD_CONFIG,"Outbound bind address '%s' didn't parse. Ignoring.",
|
ext_addr = &options->_OutboundBindAddressIPv6;
|
||||||
options->OutboundBindAddress);
|
if (ext_addr) {
|
||||||
} else {
|
struct sockaddr_storage ext_addr_sa;
|
||||||
if (bind(s, (struct sockaddr*)&ext_addr,
|
socklen_t ext_addr_len = 0;
|
||||||
(socklen_t)sizeof(ext_addr)) < 0) {
|
memset(&ext_addr_sa, 0, sizeof(ext_addr_sa));
|
||||||
*socket_error = tor_socket_errno(s);
|
ext_addr_len = tor_addr_to_sockaddr(ext_addr, 0,
|
||||||
log_warn(LD_NET,"Error binding network socket: %s",
|
(struct sockaddr *) &ext_addr_sa,
|
||||||
tor_socket_strerror(*socket_error));
|
sizeof(ext_addr_sa));
|
||||||
tor_close_socket(s);
|
if (ext_addr_len == 0) {
|
||||||
return -1;
|
log_warn(LD_NET,
|
||||||
|
"Error converting OutboundBindAddress %s into sockaddr. "
|
||||||
|
"Ignoring.", fmt_addr(ext_addr));
|
||||||
|
} else {
|
||||||
|
if (bind(s, (struct sockaddr *) &ext_addr_sa, ext_addr_len) < 0) {
|
||||||
|
*socket_error = tor_socket_errno(s);
|
||||||
|
log_warn(LD_NET,"Error binding network socket to %s: %s",
|
||||||
|
fmt_addr(ext_addr),
|
||||||
|
tor_socket_strerror(*socket_error));
|
||||||
|
tor_close_socket(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -3028,7 +3028,11 @@ typedef struct {
|
|||||||
/** Addresses to bind for listening for control connections. */
|
/** Addresses to bind for listening for control connections. */
|
||||||
config_line_t *ControlListenAddress;
|
config_line_t *ControlListenAddress;
|
||||||
/** Local address to bind outbound sockets */
|
/** Local address to bind outbound sockets */
|
||||||
char *OutboundBindAddress;
|
config_line_t *OutboundBindAddress;
|
||||||
|
/** IPv4 address derived from OutboundBindAddress. */
|
||||||
|
tor_addr_t _OutboundBindAddressIPv4;
|
||||||
|
/** IPv6 address derived from OutboundBindAddress. */
|
||||||
|
tor_addr_t _OutboundBindAddressIPv6;
|
||||||
/** Directory server only: which versions of
|
/** Directory server only: which versions of
|
||||||
* Tor should we tell users to run? */
|
* Tor should we tell users to run? */
|
||||||
config_line_t *RecommendedVersions;
|
config_line_t *RecommendedVersions;
|
||||||
|
|||||||
Reference in New Issue
Block a user