Allow multiple Bind directives.

Try all the addresses specified with Bind in order. This is necessary
e.g. for maintaining IPv4+6 connectivity while still being restricted to
one interface.
This commit is contained in:
Anton Khirnov 2020-08-26 12:32:27 +02:00 committed by rofl0r
parent 2b49ef0e0f
commit 3bb14e0440
4 changed files with 47 additions and 9 deletions

View File

@ -58,6 +58,8 @@ only on one specific address.
This allows you to specify which address Tinyproxy will bind
to for outgoing connections to web servers or upstream proxies.
This parameter may be specified multiple times, then Tinyproxy
will try all the specified addresses in order.
=item B<BindSame>

View File

@ -291,6 +291,7 @@ void free_config (struct config_s *conf)
safefree (conf->group);
stringlist_free(conf->basicauth_list);
stringlist_free(conf->listen_addrs);
stringlist_free(conf->bind_addrs);
#ifdef FILTER_ENABLE
safefree (conf->filter);
#endif /* FILTER_ENABLE */
@ -302,7 +303,6 @@ void free_config (struct config_s *conf)
free_upstream_list (conf->upstream_list);
#endif /* UPSTREAM_SUPPORT */
safefree (conf->pidpath);
safefree (conf->bind_address);
safefree (conf->via_proxy_name);
if (conf->errorpages) {
it = 0;
@ -796,12 +796,27 @@ static HANDLE_FUNC (handle_deny)
static HANDLE_FUNC (handle_bind)
{
int r = set_string_arg (&conf->bind_address, line, &match[2]);
char *arg = get_string_arg (line, &match[2]);
if (arg == NULL) {
return -1;
}
if (conf->bind_addrs == NULL) {
conf->bind_addrs = sblist_new(sizeof(char*), 16);
if (conf->bind_addrs == NULL) {
CP_WARN ("Could not create a list "
"of bind addresses.", "");
safefree(arg);
return -1;
}
}
sblist_add (conf->bind_addrs, &arg);
if (r)
return r;
log_message (LOG_INFO,
"Outgoing connections bound to IP %s", conf->bind_address);
"Added bind address [%s] for outgoing connections.", arg);
return 0;
}

View File

@ -68,7 +68,7 @@ struct config_s {
#endif /* UPSTREAM_SUPPORT */
char *pidpath;
unsigned int idletimeout;
char *bind_address;
sblist *bind_addrs;
unsigned int bindsame;
/*

View File

@ -34,6 +34,7 @@
#include "text.h"
#include "conf.h"
#include "loop.h"
#include "sblist.h"
/*
* Return a human readable error for getaddrinfo() and getnameinfo().
@ -87,6 +88,26 @@ bind_socket (int sockfd, const char *addr, int family)
return sockfd;
}
/**
* Try binding the given socket to supplied addresses, stopping when one succeeds.
*/
static int
bind_socket_list (int sockfd, sblist *addresses, int family)
{
size_t nb_addresses = sblist_getsize(addresses);
size_t i;
for (i = 0; i < nb_addresses; i++) {
const char *address = *(const char **)sblist_get(addresses, i);
if (bind_socket(sockfd, address, family) >= 0) {
log_message(LOG_INFO, "Bound to %s", address);
return 0;
}
}
return -1;
}
/*
* Open a connection to a remote host. It's been re-written to use
* the getaddrinfo() library function, which allows for a protocol
@ -134,8 +155,8 @@ int opensock (const char *host, int port, const char *bind_to)
close (sockfd);
continue; /* can't bind, so try again */
}
} else if (config->bind_address) {
if (bind_socket (sockfd, config->bind_address,
} else if (config->bind_addrs) {
if (bind_socket_list (sockfd, config->bind_addrs,
res->ai_family) < 0) {
close (sockfd);
continue; /* can't bind, so try again */