summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorguenther <>2015-10-08 20:13:45 +0000
committerguenther <>2015-10-08 20:13:45 +0000
commit92b71dd957251375dfc9dbd99f6bf56b6d38859f (patch)
tree5f7853a5034e4a35bd5516dde7eb47278631871f /src
parentda19b923ec32060e1d52bb5b8ccfbe22ba01f96f (diff)
downloadopenbsd-92b71dd957251375dfc9dbd99f6bf56b6d38859f.tar.gz
openbsd-92b71dd957251375dfc9dbd99f6bf56b6d38859f.tar.bz2
openbsd-92b71dd957251375dfc9dbd99f6bf56b6d38859f.zip
If getaddrinfo() succeeds, then don't try look ups with other flags, even
if the connect()s failed. In concert with some resolver fixes in libc, this lets ntpd be tame()ed problem isolated by theo, who had fun untangling the libc and libtls behaviors to place blame for not being able to tame ntpd ok beck@ deraadt@ jsing@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libtls/tls_client.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c
index af1b05ab71..68b0f32226 100644
--- a/src/lib/libtls/tls_client.c
+++ b/src/lib/libtls/tls_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_client.c,v 1.30 2015/09/29 13:10:53 jsing Exp $ */ 1/* $OpenBSD: tls_client.c,v 1.31 2015/10/08 20:13:45 guenther Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -44,42 +44,6 @@ tls_client(void)
44 return (ctx); 44 return (ctx);
45} 45}
46 46
47static int
48tls_connect_host(struct tls *ctx, const char *host, const char *port,
49 int af, int flag)
50{
51 struct addrinfo hints, *res, *res0;
52 int s = -1;
53
54 memset(&hints, 0, sizeof(hints));
55 hints.ai_family = af;
56 hints.ai_socktype = SOCK_STREAM;
57 hints.ai_flags = flag;
58
59 if ((s = getaddrinfo(host, port, &hints, &res0)) != 0) {
60 tls_set_error(ctx, "%s", gai_strerror(s));
61 return (-1);
62 }
63 for (res = res0; res; res = res->ai_next) {
64 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
65 if (s == -1) {
66 tls_set_error(ctx, "socket");
67 continue;
68 }
69 if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
70 tls_set_error(ctx, "connect");
71 close(s);
72 s = -1;
73 continue;
74 }
75
76 break; /* Connected. */
77 }
78 freeaddrinfo(res0);
79
80 return (s);
81}
82
83int 47int
84tls_connect(struct tls *ctx, const char *host, const char *port) 48tls_connect(struct tls *ctx, const char *host, const char *port)
85{ 49{
@@ -90,6 +54,7 @@ int
90tls_connect_servername(struct tls *ctx, const char *host, const char *port, 54tls_connect_servername(struct tls *ctx, const char *host, const char *port,
91 const char *servername) 55 const char *servername)
92{ 56{
57 struct addrinfo hints, *res, *res0;
93 const char *h = NULL, *p = NULL; 58 const char *h = NULL, *p = NULL;
94 char *hs = NULL, *ps = NULL; 59 char *hs = NULL, *ps = NULL;
95 int rv = -1, s = -1, ret; 60 int rv = -1, s = -1, ret;
@@ -132,10 +97,43 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port,
132 * sure that connection attempts to numeric addresses and especially 97 * sure that connection attempts to numeric addresses and especially
133 * 127.0.0.1 or ::1 loopback addresses are always possible. 98 * 127.0.0.1 or ::1 loopback addresses are always possible.
134 */ 99 */
135 if ((s = tls_connect_host(ctx, h, p, AF_INET, AI_NUMERICHOST)) == -1 && 100 memset(&hints, 0, sizeof(hints));
136 (s = tls_connect_host(ctx, h, p, AF_INET6, AI_NUMERICHOST)) == -1 && 101 hints.ai_socktype = SOCK_STREAM;
137 (s = tls_connect_host(ctx, h, p, AF_UNSPEC, AI_ADDRCONFIG)) == -1) 102
138 goto err; 103 /* try as an IPv4 literal */
104 hints.ai_family = AF_INET;
105 hints.ai_flags = AI_NUMERICHOST;
106 if (getaddrinfo(h, p, &hints, &res0) != 0) {
107 /* try again as an IPv6 literal */
108 hints.ai_family = AF_INET6;
109 if (getaddrinfo(h, p, &hints, &res0) != 0) {
110 /* last try, with name resolution and save the error */
111 hints.ai_family = AF_UNSPEC;
112 hints.ai_flags = AI_ADDRCONFIG;
113 if ((s = getaddrinfo(h, p, &hints, &res0)) != 0) {
114 tls_set_error(ctx, "%s", gai_strerror(s));
115 goto err;
116 }
117 }
118 }
119
120 /* It was resolved somehow; now try connecting to what we got */
121 for (res = res0; res; res = res->ai_next) {
122 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
123 if (s == -1) {
124 tls_set_error(ctx, "socket");
125 continue;
126 }
127 if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
128 tls_set_error(ctx, "connect");
129 close(s);
130 s = -1;
131 continue;
132 }
133
134 break; /* Connected. */
135 }
136 freeaddrinfo(res0);
139 137
140 if (servername == NULL) 138 if (servername == NULL)
141 servername = h; 139 servername = h;