diff options
author | des <des@FreeBSD.org> | 2003-03-03 12:35:03 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2003-03-03 12:35:03 +0000 |
commit | 66c619c7d8ca78fefc1c7260ba40ae261ae79e8b (patch) | |
tree | 974cb3f0e590239d652417eb76c251441678ad92 /lib/libfetch/common.c | |
parent | 0ae911eb0e57eebb61c50c02ddf69aa67ed19599 (diff) | |
download | FreeBSD-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/common.c')
-rw-r--r-- | lib/libfetch/common.c | 35 |
1 files changed, 32 insertions, 3 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) { |