Add more dual stack consideration.

-Should retry as much as possible when dest addr and
   source addr(specified with -s option) address family
   missmatch happend

Approved by: jkh
This commit is contained in:
Yoshinobu Inoue 2000-02-12 17:59:06 +00:00
parent 319c8e321c
commit e7e960abeb
4 changed files with 71 additions and 16 deletions

View File

@ -219,26 +219,47 @@ url_get(origline, proxyenv)
{
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s == -1) {
res = res->ai_next;
if (res)
continue;
warn("Can't create socket");
goto cleanup_url_get;
}
if (dobind && bind(s, (struct sockaddr *)&bindto,
((struct sockaddr *)&bindto)->sa_len) == -1) {
getnameinfo((struct sockaddr *)&bindto,
((struct sockaddr *)&bindto)->sa_len,
if (dobind) {
struct addrinfo *bindres;
int binderr = -1;
for (bindres = bindres0;
bindres != NULL;
bindres = bindres->ai_next)
if (bindres->ai_family == res->ai_family)
break;
if (bindres == NULL)
bindres = bindres0;
binderr = bind(s, bindres->ai_addr, bindres->ai_addrlen);
if (binderr == -1)
{
res = res->ai_next;
if (res) {
(void)close(s);
continue;
}
getnameinfo(bindres->ai_addr, bindres->ai_addrlen,
nameinfo, sizeof(nameinfo), NULL, 0,
NI_NUMERICHOST|NI_WITHSCOPEID);
/* XXX check error? */
warn("Can't bind to %s", nameinfo);
goto cleanup_url_get;
}
}
if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
close(s);
res = res->ai_next;
if (res)
if (res) {
(void)close(s);
continue;
}
warn("Can't connect to %s", host);
goto cleanup_url_get;
}

View File

@ -143,19 +143,40 @@ hookup(host0, port)
while (1) {
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0) {
res = res->ai_next;
if (res)
continue;
warn("socket");
code = -1;
return (0);
}
if (dobind &&
bind(s, (struct sockaddr *)&bindto,
((struct sockaddr *)&bindto)->sa_len) == -1) {
if (dobind) {
struct addrinfo *bindres;
int binderr = -1;
for (bindres = bindres0;
bindres != NULL;
bindres = bindres->ai_next)
if (bindres->ai_family == res->ai_family)
break;
if (bindres == NULL)
bindres = bindres0;
binderr = bind(s, bindres->ai_addr,
bindres->ai_addrlen);
if (binderr == -1)
{
res = res->ai_next;
if (res) {
(void)close(s);
continue;
}
warn("bind");
goto next;
code = -1;
goto bad;
}
}
if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
break;
next:
if (res->ai_next) {
char hname[INET6_ADDRSTRLEN];
getnameinfo(res->ai_addr, res->ai_addrlen,
@ -1159,10 +1180,24 @@ initconn()
warn("socket");
return (1);
}
if (dobind && bind(data, (struct sockaddr *)&bindto,
((struct sockaddr *)&bindto)->sa_len) == -1) {
if (dobind) {
struct addrinfo *bindres;
int binderr = -1;
for (bindres = bindres0;
bindres != NULL;
bindres = bindres->ai_next)
if (bindres->ai_family == data_addr.su_family)
break;
if (bindres == NULL)
bindres = bindres0;
binderr = bind(data, bindres->ai_addr,
bindres->ai_addrlen);
if (binderr == -1)
{
warn("bind");
goto bad;
}
}
if ((options & SO_DEBUG) &&
setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,

View File

@ -144,7 +144,7 @@ char *httpport; /* port number to use for http connections */
char *gateport; /* port number to use for gateftp connections */
int dobind; /* bind to specific address */
struct sockaddr_storage bindto; /* address to bind to */
struct addrinfo * bindres0; /* addrinfo for address to bind to */
jmp_buf toplevel; /* non-local goto stuff for cmd scanner */

View File

@ -237,8 +237,7 @@ main(argc, argv)
warnx("%s", strerror(errno));
exit(1);
}
memcpy(&bindto, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
bindres0 = res;
}
/*