diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libtls/tls_client.c | 80 |
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 | ||
47 | static int | ||
48 | tls_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 | |||
83 | int | 47 | int |
84 | tls_connect(struct tls *ctx, const char *host, const char *port) | 48 | tls_connect(struct tls *ctx, const char *host, const char *port) |
85 | { | 49 | { |
@@ -90,6 +54,7 @@ int | |||
90 | tls_connect_servername(struct tls *ctx, const char *host, const char *port, | 54 | tls_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; |