mirror of
https://repo.or.cz/socat.git
synced 2025-07-14 23:33:23 +00:00
Preferred IP version sorts getaddrionf() results
This commit is contained in:
parent
2d282f5608
commit
277f0d755d
16 changed files with 331 additions and 146 deletions
86
xio-socks.c
86
xio-socks.c
|
@ -54,6 +54,8 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
|||
union sockaddr_union us_sa, *us = &us_sa;
|
||||
socklen_t uslen = sizeof(us_sa);
|
||||
struct addrinfo *themlist, *themp;
|
||||
struct addrinfo **ai_sorted;
|
||||
int i;
|
||||
bool needbind = false;
|
||||
bool lowport = false;
|
||||
char infobuff[256];
|
||||
|
@ -72,7 +74,6 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
|||
targetname = argv[2];
|
||||
targetport = argv[3];
|
||||
|
||||
xioinit_ip(xfd, &pf);
|
||||
xfd->howtoend = END_SHUTDOWN;
|
||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||
applyopts(-1, opts, PH_INIT);
|
||||
|
@ -82,28 +83,39 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
|||
retropt_bool(opts, OPT_FORK, &dofork);
|
||||
|
||||
result = _xioopen_socks4_prepare(targetport, opts, &socksport, sockhead, &buflen);
|
||||
if (result != STAT_OK) return result;
|
||||
result =
|
||||
_xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport,
|
||||
&pf, ipproto,
|
||||
xfd->para.socket.ip.ai_flags,
|
||||
xfd->para.socket.ip.res_opts,
|
||||
&themlist, us, &uslen,
|
||||
&needbind, &lowport, socktype);
|
||||
if (result != STAT_OK)
|
||||
return result;
|
||||
|
||||
Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"",
|
||||
targetname,
|
||||
ntohs(sockhead->port),
|
||||
sockdname, socksport, sockhead->userid);
|
||||
|
||||
do { /* loop over failed connect and socks-request attempts */
|
||||
i = 0;
|
||||
do { /* loop over retries (failed connect and socks-request attempts) */
|
||||
|
||||
#if WITH_RETRY
|
||||
if (xfd->forever || xfd->retry) {
|
||||
level = E_INFO;
|
||||
} else
|
||||
#endif /* WITH_RETRY */
|
||||
level = E_ERROR;
|
||||
level = E_INFO;
|
||||
|
||||
result =
|
||||
_xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport,
|
||||
&pf, ipproto,
|
||||
xfd->para.socket.ip.ai_flags,
|
||||
xfd->para.socket.ip.res_opts,
|
||||
&themlist, us, &uslen,
|
||||
&needbind, &lowport, socktype);
|
||||
|
||||
/* Count addrinfo entries */
|
||||
themp = themlist;
|
||||
i = 0;
|
||||
while (themp != NULL) {
|
||||
++i;
|
||||
themp = themp->ai_next;
|
||||
}
|
||||
ai_sorted = Calloc((i+1), sizeof(struct addrinfo *));
|
||||
if (ai_sorted == NULL)
|
||||
return STAT_RETRYLATER;
|
||||
/* Generate a list of addresses sorted by preferred ip version */
|
||||
_xio_sort_ip_addresses(themlist, ai_sorted);
|
||||
|
||||
/* we try to resolve the target address _before_ connecting to the socks
|
||||
server: this avoids unnecessary socks connects and timeouts */
|
||||
|
@ -124,41 +136,51 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
|||
return result;
|
||||
}
|
||||
|
||||
themp = themlist;
|
||||
/* loop over themlist */
|
||||
i = 0;
|
||||
themp = ai_sorted[i++];
|
||||
while (themp != NULL) {
|
||||
Notice1("opening connection to %s",
|
||||
sockaddr_info(themp->ai_addr, themp->ai_addrlen,
|
||||
infobuff, sizeof(infobuff)));
|
||||
#if WITH_RETRY
|
||||
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
|
||||
level = E_INFO;
|
||||
} else
|
||||
#endif /* WITH_RETRY */
|
||||
level = E_ERROR;
|
||||
|
||||
/* this cannot fork because we retrieved fork option above */
|
||||
result =
|
||||
_xioopen_connect(xfd,
|
||||
needbind?us:NULL, sizeof(*us),
|
||||
themp->ai_addr, themp->ai_addrlen,
|
||||
opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level);
|
||||
if (result == STAT_OK)
|
||||
break;
|
||||
themp = themp->ai_next;
|
||||
if (themp == NULL) {
|
||||
result = STAT_RETRYLATER;
|
||||
result =
|
||||
_xioopen_connect(xfd,
|
||||
needbind?us:NULL, sizeof(*us),
|
||||
themp->ai_addr, themp->ai_addrlen,
|
||||
opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP,
|
||||
lowport, level);
|
||||
if (result == STAT_OK)
|
||||
break;
|
||||
themp = ai_sorted[i++];
|
||||
if (themp == NULL) {
|
||||
result = STAT_RETRYLATER;
|
||||
}
|
||||
}
|
||||
switch (result) {
|
||||
case STAT_OK: break;
|
||||
#if WITH_RETRY
|
||||
case STAT_RETRYLATER:
|
||||
case STAT_RETRYNOW:
|
||||
if (xfd->forever || xfd->retry--) {
|
||||
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
|
||||
if (xfd->forever || xfd->retry) {
|
||||
--xfd->retry;
|
||||
if (result == STAT_RETRYLATER)
|
||||
Nanosleep(&xfd->intervall, NULL);
|
||||
continue;
|
||||
}
|
||||
#endif /* WITH_RETRY */
|
||||
default:
|
||||
free(ai_sorted);
|
||||
xiofreeaddrinfo(themlist);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
xiofreeaddrinfo(themlist);
|
||||
applyopts(xfd->fd, opts, PH_ALL);
|
||||
|
||||
if ((result = _xio_openlate(xfd, opts)) < 0)
|
||||
return result;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue