From f50a654323bbfeb0de53aa2178755b282bcc9d22 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 25 Jan 2016 00:18:33 +0100 Subject: [PATCH] http: add support for specifying ipv4/ipv6 preference Signed-off-by: Felix Fietkau --- uclient-fetch.c | 17 +++++++++++++++-- uclient-http.c | 27 ++++++++++++++++++++++++++- uclient.h | 1 + 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/uclient-fetch.c b/uclient-fetch.c index 851994f..f65fab2 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -18,6 +18,7 @@ #define _GNU_SOURCE #include +#include #include #include #include @@ -439,6 +440,8 @@ static int usage(const char *progname) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" + " -4: Use IPv4 only\n" + " -6: Use IPv6 only\n" " -q: Turn off status messages\n" " -O : Redirect output to file (use \"-\" for stdout)\n" " -P : Set directory for output files\n" @@ -530,11 +533,12 @@ int main(int argc, char **argv) bool has_cert = false; int i, ch; int rc; + int af = -1; signal(SIGPIPE, SIG_IGN); init_ustream_ssl(); - while ((ch = getopt_long(argc, argv, "cO:P:qsT:U:Y:", longopts, &longopt_idx)) != -1) { + while ((ch = getopt_long(argc, argv, "46cO:P:qsT:U:Y:", longopts, &longopt_idx)) != -1) { switch(ch) { case 0: switch (longopt_idx) { @@ -584,6 +588,12 @@ int main(int argc, char **argv) return usage(progname); } break; + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; case 'c': resume = true; break; @@ -652,7 +662,8 @@ int main(int argc, char **argv) proxy_url = get_proxy_url(argv[0]); if (proxy_url) { cl = uclient_new(proxy_url, auth_str, &cb); - uclient_set_proxy_url(cl, argv[0], NULL); + if (cl) + uclient_set_proxy_url(cl, argv[0], NULL); } else { cl = uclient_new(argv[0], auth_str, &cb); } @@ -660,6 +671,8 @@ int main(int argc, char **argv) fprintf(stderr, "Failed to allocate uclient context\n"); return 1; } + if (af >= 0) + uclient_http_set_address_family(cl, af); if (ssl_ctx && default_certs) init_ca_cert(); diff --git a/uclient-http.c b/uclient-http.c index 5e5f996..f080e41 100644 --- a/uclient-http.c +++ b/uclient-http.c @@ -15,6 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -90,6 +91,8 @@ struct uclient_http { long read_chunked; long content_length; + int usock_flags; + uint32_t nc; struct blob_buf headers; @@ -120,7 +123,7 @@ static int uclient_do_connect(struct uclient_http *uh, const char *port) memset(&uh->uc.remote_addr, 0, sizeof(uh->uc.remote_addr)); - fd = usock_inet(USOCK_TCP, uh->uc.url->host, port, &uh->uc.remote_addr); + fd = usock_inet(USOCK_TCP | uh->usock_flags, uh->uc.url->host, port, &uh->uc.remote_addr); if (fd < 0) return -1; @@ -1129,6 +1132,28 @@ int uclient_http_set_ssl_ctx(struct uclient *cl, const struct ustream_ssl_ops *o return 0; } +int uclient_http_set_address_family(struct uclient *cl, int af) +{ + struct uclient_http *uh = container_of(cl, struct uclient_http, uc); + + if (cl->backend != &uclient_backend_http) + return -1; + + switch (af) { + case AF_INET: + uh->usock_flags = USOCK_IPV4ONLY; + break; + case AF_INET6: + uh->usock_flags = USOCK_IPV6ONLY; + break; + default: + uh->usock_flags = 0; + break; + } + + return 0; +} + const struct uclient_backend uclient_backend_http = { .prefix = uclient_http_prefix, diff --git a/uclient.h b/uclient.h index 504fc35..e3695db 100644 --- a/uclient.h +++ b/uclient.h @@ -125,5 +125,6 @@ int uclient_http_redirect(struct uclient *cl); int uclient_http_set_ssl_ctx(struct uclient *cl, const struct ustream_ssl_ops *ops, struct ustream_ssl_ctx *ctx, bool require_validation); +int uclient_http_set_address_family(struct uclient *cl, int af); #endif -- 2.11.0