diff options
author | 2015-02-09 09:23:39 +0000 | |
---|---|---|
committer | 2015-02-09 09:23:39 +0000 | |
commit | 8e5d73c6d3f09827a6dc94b313c1c567f2e4b5e1 (patch) | |
tree | 071a9055cbb491eb8331da2848d3c703f044bf8a /lib | |
parent | Do not use USRSTACK when VM_MIN_KERNEL_ADDRESS is what you really mean. (diff) | |
download | wireguard-openbsd-8e5d73c6d3f09827a6dc94b313c1c567f2e4b5e1.tar.xz wireguard-openbsd-8e5d73c6d3f09827a6dc94b313c1c567f2e4b5e1.zip |
When parsing the host in tls_connect(), first check if it is a numeric
IPv4 or IPv6 address before trying to resolve the address with the
AI_ADDRCONFIG flag set. This makes sure that attempts to connect to
numeric IPs or loopback addresses are always possible and not
prevented by AI_ADDRCONFIG.
OK jsing@ tedu@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libtls/tls_client.c | 78 |
1 files changed, 49 insertions, 29 deletions
diff --git a/lib/libtls/tls_client.c b/lib/libtls/tls_client.c index 0894ce63336..907c334f156 100644 --- a/lib/libtls/tls_client.c +++ b/lib/libtls/tls_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_client.c,v 1.12 2015/02/08 04:12:34 reyk Exp $ */ +/* $OpenBSD: tls_client.c,v 1.13 2015/02/09 09:23:39 reyk Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -44,10 +44,45 @@ tls_client(void) return (ctx); } +static int +tls_connect_host(struct tls *ctx, const char *host, const char *port, + int af, int flag) +{ + struct addrinfo hints, *res, *res0; + int s = -1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = flag; + + if ((s = getaddrinfo(host, port, &hints, &res0)) != 0) { + tls_set_error(ctx, "%s", gai_strerror(s)); + return (-1); + } + for (res = res0; res; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == -1) { + tls_set_error(ctx, "socket"); + continue; + } + if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { + tls_set_error(ctx, "connect"); + close(s); + s = -1; + continue; + } + + break; /* Connected. */ + } + freeaddrinfo(res0); + + return (s); +} + int tls_connect(struct tls *ctx, const char *host, const char *port) { - struct addrinfo hints, *res, *res0; const char *h = NULL, *p = NULL; char *hs = NULL, *ps = NULL; int rv = -1, s = -1, ret; @@ -79,33 +114,18 @@ tls_connect(struct tls *ctx, const char *host, const char *port) h = (hs != NULL) ? hs : host; p = (ps != NULL) ? ps : port; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG; - - if ((ret = getaddrinfo(h, p, &hints, &res0)) != 0) { - tls_set_error(ctx, "%s", gai_strerror(ret)); - goto err; - } - for (res = res0; res; res = res->ai_next) { - s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (s == -1) { - tls_set_error(ctx, "socket"); - continue; - } - if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { - tls_set_error(ctx, "connect"); - close(s); - s = -1; - continue; - } - - break; /* Connected. */ - } - freeaddrinfo(res0); - - if (s == -1) + /* + * First check if the host is specified as a numeric IP address, + * either IPv4 or IPv6, before trying to resolve the host. + * The AI_ADDRCONFIG resolver option will not return IPv4 or IPv6 + * records if it is not configured on an interface; not considering + * loopback addresses. Checking the numeric addresses first makes + * sure that connection attempts to numeric addresses and especially + * 127.0.0.1 or ::1 loopback addresses are always possible. + */ + if ((s = tls_connect_host(ctx, h, p, AF_INET, AI_NUMERICHOST)) == -1 && + (s = tls_connect_host(ctx, h, p, AF_INET6, AI_NUMERICHOST)) == -1 && + (s = tls_connect_host(ctx, h, p, AF_UNSPEC, AI_ADDRCONFIG)) == -1) goto err; if (tls_connect_socket(ctx, s, h) != 0) { |