summaryrefslogtreecommitdiffstats
path: root/lib/libfetch
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2003-03-03 12:35:03 +0000
committerdes <des@FreeBSD.org>2003-03-03 12:35:03 +0000
commit66c619c7d8ca78fefc1c7260ba40ae261ae79e8b (patch)
tree974cb3f0e590239d652417eb76c251441678ad92 /lib/libfetch
parent0ae911eb0e57eebb61c50c02ddf69aa67ed19599 (diff)
downloadFreeBSD-src-66c619c7d8ca78fefc1c7260ba40ae261ae79e8b.zip
FreeBSD-src-66c619c7d8ca78fefc1c7260ba40ae261ae79e8b.tar.gz
Add and document support for a FETCH_BIND_ADDRESS environment variable
specifying a local address to bind sockets to. Caveat: lightly tested. PR: bin/37572
Diffstat (limited to 'lib/libfetch')
-rw-r--r--lib/libfetch/common.c35
-rw-r--r--lib/libfetch/common.h1
-rw-r--r--lib/libfetch/fetch.35
3 files changed, 37 insertions, 4 deletions
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
index c01837a..ea1c81d 100644
--- a/lib/libfetch/common.c
+++ b/lib/libfetch/common.c
@@ -227,6 +227,28 @@ _fetch_ref(conn_t *conn)
/*
+ * Bind a socket to a specific local address
+ */
+int
+_fetch_bind(int sd, int af, const char *addr)
+{
+ struct addrinfo hints, *res, *res0;
+ int err;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ if ((err = getaddrinfo(addr, NULL, &hints, &res0)) != 0)
+ return (-1);
+ for (res = res0; res; res = res->ai_next)
+ if (bind(sd, res->ai_addr, res->ai_addrlen) == 0)
+ return (0);
+ return (-1);
+}
+
+
+/*
* Establish a TCP connection to the specified port on the specified host.
*/
conn_t *
@@ -234,6 +256,7 @@ _fetch_connect(const char *host, int port, int af, int verbose)
{
conn_t *conn;
char pbuf[10];
+ const char *bindaddr;
struct addrinfo hints, *res, *res0;
int sd, err;
@@ -252,19 +275,25 @@ _fetch_connect(const char *host, int port, int af, int verbose)
_netdb_seterr(err);
return (NULL);
}
+ bindaddr = getenv("FETCH_BIND_ADDRESS");
if (verbose)
_fetch_info("connecting to %s:%d", host, port);
/* try to connect */
- for (sd = -1, res = res0; res; res = res->ai_next) {
+ for (sd = -1, res = res0; res; sd = -1, res = res->ai_next) {
if ((sd = socket(res->ai_family, res->ai_socktype,
res->ai_protocol)) == -1)
continue;
- if (connect(sd, res->ai_addr, res->ai_addrlen) != -1)
+ if (bindaddr != NULL && *bindaddr != '\0' &&
+ _fetch_bind(sd, res->ai_family, bindaddr) != 0) {
+ _fetch_info("failed to bind to '%s'", bindaddr);
+ close(sd);
+ continue;
+ }
+ if (connect(sd, res->ai_addr, res->ai_addrlen) == 0)
break;
close(sd);
- sd = -1;
}
freeaddrinfo(res0);
if (sd == -1) {
diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h
index adc0f38..6f65259 100644
--- a/lib/libfetch/common.h
+++ b/lib/libfetch/common.h
@@ -76,6 +76,7 @@ void _fetch_syserr(void);
void _fetch_info(const char *, ...);
int _fetch_default_port(const char *);
int _fetch_default_proxy_port(const char *);
+int _fetch_bind(int, int, const char *);
conn_t *_fetch_connect(const char *, int, int, int);
conn_t *_fetch_reopen(int);
conn_t *_fetch_ref(conn_t *);
diff --git a/lib/libfetch/fetch.3 b/lib/libfetch/fetch.3
index 540b42f..5bbfa2e 100644
--- a/lib/libfetch/fetch.3
+++ b/lib/libfetch/fetch.3
@@ -444,7 +444,10 @@ Invalid URL
The accompanying error message includes a protocol-specific error code
and message, e.g. "File is not available (404 Not Found)"
.Sh ENVIRONMENT
-.Bl -tag -width FTP_PASSIVE_MODE
+.Bl -tag -width FETCH_BIND_ADDRESS
+.It Ev FETCH_BIND_ADDRESS
+Specifies a hostname or IP address to which sockets used for outgoing
+connections will be bound.
.It Ev FTP_LOGIN
Default FTP login if none was provided in the URL.
.It Ev FTP_PASSIVE_MODE
OpenPOWER on IntegriCloud