summaryrefslogtreecommitdiffstats
path: root/usr.bin/ftp/ftp.c
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/ftp.c
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/ftp.c')
-rw-r--r--usr.bin/ftp/ftp.c49
1 files changed, 42 insertions, 7 deletions
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,
OpenPOWER on IntegriCloud