Skip to content

Commit 2702f85

Browse files
committed
improve new code selecting connection target by bindaddr family
the code added in 6ecc398 was modified to - better match the rest of codestyle - don't print gratuitous warning if no matching addrinfo record was found - always select outgoing socket type according to first addrinfo result, like in the past, rather than enforcing the af of bindaddr even if no matching record exists. - only call bind() if the selected addrinfo record matches the bind addr as a sideeffect of the latter, bind() will no longer be called when there's no DNS record matching the address family of the bindaddr, which means the connection will use the system default route for the target. whether this aligns with user's expectations remain to be seen, but imo it's preferable to make the connection work rather than enforcing that no packet goes out on another interface than the one specified via bind addr.
1 parent 6ecc398 commit 2702f85

File tree

1 file changed

+9
-16
lines changed

1 file changed

+9
-16
lines changed

sockssrv.c

+9-16
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,12 @@ struct thread {
111111
static void dolog(const char* fmt, ...) { }
112112
#endif
113113

114-
static int family_choose(struct addrinfo* remote, union sockaddr_union* bind_addr) {
115-
int family = SOCKADDR_UNION_AF(bind_addr);
116-
return family == AF_UNSPEC ? remote->ai_family : family;
117-
}
118-
119114
static struct addrinfo* addr_choose(struct addrinfo* list, union sockaddr_union* bind_addr) {
120-
int family = SOCKADDR_UNION_AF(bind_addr);
121-
if(family == AF_UNSPEC) return list;
115+
int af = SOCKADDR_UNION_AF(bind_addr);
116+
if(af == AF_UNSPEC) return list;
122117
struct addrinfo* p;
123-
for(p=list;p;p=p->ai_next) {
124-
if(p->ai_family == family) return p;
125-
}
126-
dprintf(2, "warning: address family mismatch\n");
118+
for(p=list; p; p=p->ai_next)
119+
if(p->ai_family == af) return p;
127120
return list;
128121
}
129122

@@ -162,8 +155,8 @@ static int connect_socks_target(unsigned char *buf, size_t n, struct client *cli
162155
port = (buf[minlen-2] << 8) | buf[minlen-1];
163156
/* there's no suitable errorcode in rfc1928 for dns lookup failure */
164157
if(resolve(namebuf, port, &remote)) return -EC_GENERAL_FAILURE;
165-
int family = family_choose(remote, &bind_addr);
166-
int fd = socket(family, SOCK_STREAM, 0);
158+
struct addrinfo* raddr = addr_choose(remote, &bind_addr);
159+
int fd = socket(raddr->ai_family, SOCK_STREAM, 0);
167160
if(fd == -1) {
168161
eval_errno:
169162
if(fd != -1) close(fd);
@@ -188,10 +181,10 @@ static int connect_socks_target(unsigned char *buf, size_t n, struct client *cli
188181
return -EC_GENERAL_FAILURE;
189182
}
190183
}
191-
if(SOCKADDR_UNION_AF(&bind_addr) != AF_UNSPEC && bindtoip(fd, &bind_addr) == -1)
184+
if(SOCKADDR_UNION_AF(&bind_addr) == raddr->ai_family &&
185+
bindtoip(fd, &bind_addr) == -1)
192186
goto eval_errno;
193-
struct addrinfo* addr = addr_choose(remote, &bind_addr);
194-
if(connect(fd, addr->ai_addr, addr->ai_addrlen) == -1)
187+
if(connect(fd, raddr->ai_addr, raddr->ai_addrlen) == -1)
195188
goto eval_errno;
196189

197190
freeaddrinfo(remote);

0 commit comments

Comments
 (0)