Do not protect the link socket when connecting to localhost --- src/openvpn/socket.c | 21 ++++++++++++++++++--- src/openvpn/socket.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 4fd00db..c904f94 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -691,16 +691,24 @@ create_socket (struct link_socket *sock) /* set socket to --mark packets with given value */ socket_set_mark (sock->sd, sock->mark); +} + #ifdef TARGET_ANDROID +static void protect_fd_nonlocal (int fd, const struct sockaddr* addr) +{ /* pass socket FD to management interface to pass on to VPNService API * as "protected socket" (exempt from being routed into tunnel) */ + if (addr_local (addr)) { + msg(M_DEBUG, "Address is local, not protecting socket fd %d", fd); + return; + } - management->connection.fdtosend = sock->sd; + msg(M_DEBUG, "Protecting socket fd %d", fd); + management->connection.fdtosend = fd; management_android_control (management, "PROTECTFD", __func__); -#endif - } +#endif /* * Functions used for establishing a TCP stream connection. @@ -934,6 +942,10 @@ openvpn_connect (socket_descriptor_t sd, { int status = 0; +#ifdef TARGET_ANDROID + protect_fd_nonlocal(sd, remote); +#endif + #ifdef CONNECT_NONBLOCK set_nonblock (sd); status = connect (sd, remote, af_addr_size(remote->sa_family)); @@ -1791,6 +1803,9 @@ link_socket_init_phase2 (struct link_socket *sock, phase2_socks_client (sock, sig_info); #endif } +#ifdef TARGET_ANDROID + protect_fd_nonlocal (sock->sd, &sock->info.lsa->actual.dest.addr.sa); +#endif if (sig_info && sig_info->signal_received) goto done; } diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h index 75f2fa5..4c18b74 100644 --- a/src/openvpn/socket.h +++ b/src/openvpn/socket.h @@ -598,6 +598,23 @@ addr_defined (const struct openvpn_sockaddr *addr) default: return 0; } } + +static inline bool +addr_local (const struct sockaddr *addr) +{ + if (!addr) + return false; + switch (addr->sa_family) { + case AF_INET: + return ((const struct sockaddr_in*)addr)->sin_addr.s_addr == htonl(INADDR_LOOPBACK); + case AF_INET6: + return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6*)addr)->sin6_addr); + default: + return false; + } +} + + static inline bool addr_defined_ipi (const struct link_socket_actual *lsa) { -- 1.7.9.5