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:
parent
2b49ef0e0f
commit
3bb14e0440
@ -58,6 +58,8 @@ only on one specific address.
|
|||||||
|
|
||||||
This allows you to specify which address Tinyproxy will bind
|
This allows you to specify which address Tinyproxy will bind
|
||||||
to for outgoing connections to web servers or upstream proxies.
|
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>
|
=item B<BindSame>
|
||||||
|
|
||||||
|
25
src/conf.c
25
src/conf.c
@ -291,6 +291,7 @@ void free_config (struct config_s *conf)
|
|||||||
safefree (conf->group);
|
safefree (conf->group);
|
||||||
stringlist_free(conf->basicauth_list);
|
stringlist_free(conf->basicauth_list);
|
||||||
stringlist_free(conf->listen_addrs);
|
stringlist_free(conf->listen_addrs);
|
||||||
|
stringlist_free(conf->bind_addrs);
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
safefree (conf->filter);
|
safefree (conf->filter);
|
||||||
#endif /* FILTER_ENABLE */
|
#endif /* FILTER_ENABLE */
|
||||||
@ -302,7 +303,6 @@ void free_config (struct config_s *conf)
|
|||||||
free_upstream_list (conf->upstream_list);
|
free_upstream_list (conf->upstream_list);
|
||||||
#endif /* UPSTREAM_SUPPORT */
|
#endif /* UPSTREAM_SUPPORT */
|
||||||
safefree (conf->pidpath);
|
safefree (conf->pidpath);
|
||||||
safefree (conf->bind_address);
|
|
||||||
safefree (conf->via_proxy_name);
|
safefree (conf->via_proxy_name);
|
||||||
if (conf->errorpages) {
|
if (conf->errorpages) {
|
||||||
it = 0;
|
it = 0;
|
||||||
@ -796,12 +796,27 @@ static HANDLE_FUNC (handle_deny)
|
|||||||
|
|
||||||
static HANDLE_FUNC (handle_bind)
|
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,
|
log_message (LOG_INFO,
|
||||||
"Outgoing connections bound to IP %s", conf->bind_address);
|
"Added bind address [%s] for outgoing connections.", arg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ struct config_s {
|
|||||||
#endif /* UPSTREAM_SUPPORT */
|
#endif /* UPSTREAM_SUPPORT */
|
||||||
char *pidpath;
|
char *pidpath;
|
||||||
unsigned int idletimeout;
|
unsigned int idletimeout;
|
||||||
char *bind_address;
|
sblist *bind_addrs;
|
||||||
unsigned int bindsame;
|
unsigned int bindsame;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
27
src/sock.c
27
src/sock.c
@ -34,6 +34,7 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
#include "sblist.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a human readable error for getaddrinfo() and getnameinfo().
|
* Return a human readable error for getaddrinfo() and getnameinfo().
|
||||||
@ -87,6 +88,26 @@ bind_socket (int sockfd, const char *addr, int family)
|
|||||||
return sockfd;
|
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
|
* Open a connection to a remote host. It's been re-written to use
|
||||||
* the getaddrinfo() library function, which allows for a protocol
|
* the getaddrinfo() library function, which allows for a protocol
|
||||||
@ -134,9 +155,9 @@ int opensock (const char *host, int port, const char *bind_to)
|
|||||||
close (sockfd);
|
close (sockfd);
|
||||||
continue; /* can't bind, so try again */
|
continue; /* can't bind, so try again */
|
||||||
}
|
}
|
||||||
} else if (config->bind_address) {
|
} else if (config->bind_addrs) {
|
||||||
if (bind_socket (sockfd, config->bind_address,
|
if (bind_socket_list (sockfd, config->bind_addrs,
|
||||||
res->ai_family) < 0) {
|
res->ai_family) < 0) {
|
||||||
close (sockfd);
|
close (sockfd);
|
||||||
continue; /* can't bind, so try again */
|
continue; /* can't bind, so try again */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user