summaryrefslogtreecommitdiffstats
path: root/usr.bin/ftp
diff options
context:
space:
mode:
authorshin <shin@FreeBSD.org>2000-02-12 17:59:06 +0000
committershin <shin@FreeBSD.org>2000-02-12 17:59:06 +0000
commitce3ac581a39661c68d153da77856c5e521e5e322 (patch)
tree5f721cc349fd60fa07883c1edea9d3e50d92730c /usr.bin/ftp
parent0a2a73d5508f74fa8b717c3afbf2c50e4c14150c (diff)
downloadFreeBSD-src-ce3ac581a39661c68d153da77856c5e521e5e322.zip
FreeBSD-src-ce3ac581a39661c68d153da77856c5e521e5e322.tar.gz
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
Diffstat (limited to 'usr.bin/ftp')
-rw-r--r--usr.bin/ftp/fetch.c33
-rw-r--r--usr.bin/ftp/ftp.c49
-rw-r--r--usr.bin/ftp/ftp_var.h2
-rw-r--r--usr.bin/ftp/main.c3
4 files changed, 71 insertions, 16 deletions
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index a494e7e..bc8adf1 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -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;
}
diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c
index 1fe1c75..c31cb94 100644
--- a/usr.bin/ftp/ftp.c
+++ b/usr.bin/ftp/ftp.c
@@ -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,
diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h
index cd9b0bd..8694bcc 100644
--- a/usr.bin/ftp/ftp_var.h
+++ b/usr.bin/ftp/ftp_var.h
@@ -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 */
diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c
index 5a1e5e6..48bf77e 100644
--- a/usr.bin/ftp/main.c
+++ b/usr.bin/ftp/main.c
@@ -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;
}
/*
OpenPOWER on IntegriCloud