sock: Allow binding outgoing connections to an interface
The current "Bind" allows IP addresses which does not work with dynamically changing IPs such as VPN. Extend "Bind" to accept an interface name if SO_BINDTODEVICE is supported (Linux). For example, "Bind tun0". Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
This commit is contained in:
parent
1801e5c552
commit
66abfe58a1
@ -60,6 +60,8 @@ This allows you to specify which address Tinyproxy will bind
|
|||||||
to for outgoing connections.
|
to for outgoing connections.
|
||||||
This parameter may be specified multiple times, then Tinyproxy
|
This parameter may be specified multiple times, then Tinyproxy
|
||||||
will try all the specified addresses in order.
|
will try all the specified addresses in order.
|
||||||
|
When SO_BINDTODEVICE present, this parameter allows interface
|
||||||
|
names.
|
||||||
|
|
||||||
=item B<BindSame>
|
=item B<BindSame>
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ Port 8888
|
|||||||
# Bind: This allows you to specify which interface will be used for
|
# Bind: This allows you to specify which interface will be used for
|
||||||
# outgoing connections. This is useful for multi-home'd machines where
|
# outgoing connections. This is useful for multi-home'd machines where
|
||||||
# you want all traffic to appear outgoing from one particular interface.
|
# you want all traffic to appear outgoing from one particular interface.
|
||||||
#
|
# This allows using the name of an interface, useful for tun devices.
|
||||||
#Bind 192.168.0.1
|
#Bind 192.168.0.1
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -225,7 +225,11 @@ struct {
|
|||||||
handle_allow),
|
handle_allow),
|
||||||
STDCONF (deny, "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
|
STDCONF (deny, "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
|
||||||
handle_deny),
|
handle_deny),
|
||||||
STDCONF (bind, "(" IP "|" IPV6 ")", handle_bind),
|
STDCONF (bind, "(" IP "|" IPV6
|
||||||
|
#ifdef SO_BINDTODEVICE
|
||||||
|
"|" INTERFACE
|
||||||
|
#endif
|
||||||
|
")", handle_bind),
|
||||||
/* other */
|
/* other */
|
||||||
STDCONF (basicauth, USERNAME WS PASSWORD, handle_basicauth),
|
STDCONF (basicauth, USERNAME WS PASSWORD, handle_basicauth),
|
||||||
STDCONF (errorfile, INT WS STR, handle_errorfile),
|
STDCONF (errorfile, INT WS STR, handle_errorfile),
|
||||||
|
@ -145,6 +145,10 @@ display_usage (void)
|
|||||||
printf (" Upstream proxy support\n");
|
printf (" Upstream proxy support\n");
|
||||||
features++;
|
features++;
|
||||||
#endif /* UPSTREAM_SUPPORT */
|
#endif /* UPSTREAM_SUPPORT */
|
||||||
|
#ifdef SO_BINDTODEVICE
|
||||||
|
printf (" BindToDevice\n");
|
||||||
|
features++;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (0 == features)
|
if (0 == features)
|
||||||
printf (" None\n");
|
printf (" None\n");
|
||||||
|
17
src/sock.c
17
src/sock.c
@ -71,6 +71,23 @@ bind_socket (int sockfd, const char *addr, int family)
|
|||||||
assert (sockfd >= 0);
|
assert (sockfd >= 0);
|
||||||
assert (addr != NULL && strlen (addr) != 0);
|
assert (addr != NULL && strlen (addr) != 0);
|
||||||
|
|
||||||
|
#ifdef SO_BINDTODEVICE
|
||||||
|
if (addr && if_nametoindex(addr)) {
|
||||||
|
struct ifreq interface = {};
|
||||||
|
|
||||||
|
strcpy(interface.ifr_name, addr);
|
||||||
|
n = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||||
|
&interface, sizeof(interface));
|
||||||
|
if (n < 0) {
|
||||||
|
log_message (LOG_INFO,
|
||||||
|
"bind_socket: SO_BINDTODEVICE to %s %s",
|
||||||
|
addr, get_gai_error (n));
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return sockfd;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
memset (&hints, 0, sizeof (struct addrinfo));
|
memset (&hints, 0, sizeof (struct addrinfo));
|
||||||
hints.ai_family = family;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
Loading…
Reference in New Issue
Block a user