Make host resolver call __connect() rather than connect() so mark isn't cleared.

Calling connect() will erase the mark set by the host resolver code because the
explicitlySelected bit of the Fwmark isn't set.  It's by design that the
explicitlySelected bit isn't set as this facilitates falling through to other
routing rules if the selected network doesn't provide a route to the DNS server
as may be the case with VPNs.

Change-Id: I60ba7c754194ead97df3ac6a6c5b3db1f446dac8
This commit is contained in:
Paul Jensen 2014-05-29 16:28:30 -04:00
parent 0f1a221b3a
commit 31ad03761d
3 changed files with 14 additions and 4 deletions

View File

@ -494,6 +494,16 @@ void res_setnetid(res_state, unsigned);
void res_setmark(res_state, unsigned);
u_int res_randomid(void);
#ifdef __i386__
# define __socketcall extern __attribute__((__cdecl__))
#else
# define __socketcall extern
#endif
__socketcall int __connect(int, const struct sockaddr*, socklen_t);
#undef __socketcall
__END_DECLS
#endif /* !_RESOLV_PRIVATE_H_ */

View File

@ -369,7 +369,7 @@ _test_connect(int pf, struct sockaddr *addr, size_t addrlen, unsigned mark) {
return 0;
int ret;
do {
ret = connect(s, addr, addrlen);
ret = __connect(s, addr, addrlen);
} while (ret < 0 && errno == EINTR);
int success = (ret == 0);
do {
@ -1803,7 +1803,7 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
return 0;
do {
ret = connect(sock, addr, len);
ret = __connect(sock, addr, len);
} while (ret == -1 && errno == EINTR);
if (ret == -1) {

View File

@ -946,7 +946,7 @@ connect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int
origflags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, origflags | O_NONBLOCK);
res = connect(sock, nsap, salen);
res = __connect(sock, nsap, salen);
if (res < 0 && errno != EINPROGRESS) {
res = -1;
goto done;
@ -1103,7 +1103,7 @@ send_dg(res_state statp,
res_nclose(statp);
return (0);
}
if (connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) {
if (__connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) {
Aerror(statp, stderr, "connect(dg)", errno, nsap,
nsaplen);
res_nclose(statp);