]>
Commit | Line | Data |
---|---|---|
95d659f0 | 1 | |
983061ed | 2 | /* |
770f051d | 3 | * $Id: ssl.cc,v 1.51 1997/05/15 23:38:02 wessels Exp $ |
983061ed | 4 | * |
30a4f2a8 | 5 | * DEBUG: section 26 Secure Sockets Layer Proxy |
6 | * AUTHOR: Duane Wessels | |
7 | * | |
42c04c16 | 8 | * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ |
30a4f2a8 | 9 | * -------------------------------------------------------- |
10 | * | |
11 | * Squid is the result of efforts by numerous individuals from the | |
12 | * Internet community. Development is led by Duane Wessels of the | |
13 | * National Laboratory for Applied Network Research and funded by | |
14 | * the National Science Foundation. | |
15 | * | |
16 | * This program is free software; you can redistribute it and/or modify | |
17 | * it under the terms of the GNU General Public License as published by | |
18 | * the Free Software Foundation; either version 2 of the License, or | |
19 | * (at your option) any later version. | |
20 | * | |
21 | * This program is distributed in the hope that it will be useful, | |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | * GNU General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU General Public License | |
27 | * along with this program; if not, write to the Free Software | |
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
29 | * | |
983061ed | 30 | */ |
983061ed | 31 | |
30a4f2a8 | 32 | #include "squid.h" |
983061ed | 33 | |
34 | typedef struct { | |
35 | char *url; | |
98ffb7e4 | 36 | char *host; /* either request->host or proxy host */ |
37 | u_short port; | |
983061ed | 38 | request_t *request; |
39 | char *mime_hdr; | |
40 | struct { | |
41 | int fd; | |
42 | int len; | |
43 | int offset; | |
44 | char *buf; | |
45 | } client, server; | |
46 | time_t timeout; | |
382d851a | 47 | int *size_ptr; /* pointer to size in an ConnStateData for logging */ |
93868820 | 48 | int proxying; |
429fdbec | 49 | int ip_lookup_pending; |
983061ed | 50 | } SslStateData; |
51 | ||
0ee4272b | 52 | static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n"; |
983061ed | 53 | |
5c5783a2 | 54 | static PF sslTimeout; |
b177367b | 55 | static void sslReadServer _PARAMS((int fd, void *)); |
56 | static void sslReadClient _PARAMS((int fd, void *)); | |
57 | static void sslWriteServer _PARAMS((int fd, void *)); | |
58 | static void sslWriteClient _PARAMS((int fd, void *)); | |
59 | static void sslConnected _PARAMS((int fd, void *)); | |
60 | static void sslProxyConnected _PARAMS((int fd, void *)); | |
b69f7771 | 61 | static IPH sslConnect; |
67508012 | 62 | static void sslErrorComplete _PARAMS((int, char *, int, int, void *)); |
63 | static void sslClose _PARAMS((SslStateData * sslState)); | |
b177367b | 64 | static void sslClientClosed _PARAMS((int fd, void *)); |
e5f6c5c2 | 65 | static void sslConnectDone _PARAMS((int fd, int status, void *data)); |
b177367b | 66 | static void sslStateFree _PARAMS((int fd, void *data)); |
b6c0e933 | 67 | static void sslPeerSelectComplete _PARAMS((peer * p, void *data)); |
68 | static void sslPeerSelectFail _PARAMS((peer * p, void *data)); | |
30a4f2a8 | 69 | |
b8d8561b | 70 | static void |
71 | sslClose(SslStateData * sslState) | |
30a4f2a8 | 72 | { |
73 | if (sslState->client.fd > -1) { | |
74 | /* remove the "unexpected" client close handler */ | |
75 | comm_remove_close_handler(sslState->client.fd, | |
b177367b | 76 | sslClientClosed, |
cd1fb0eb | 77 | sslState); |
30a4f2a8 | 78 | comm_close(sslState->client.fd); |
79 | sslState->client.fd = -1; | |
80 | } | |
81 | if (sslState->server.fd > -1) { | |
82 | comm_close(sslState->server.fd); | |
83 | } | |
84 | } | |
85 | ||
86 | /* This is called only if the client connect closes unexpectedly, | |
87 | * ie from icpDetectClientClose() */ | |
b177367b | 88 | static void |
89 | sslClientClosed(int fd, void *data) | |
30a4f2a8 | 90 | { |
b177367b | 91 | SslStateData *sslState = data; |
30a4f2a8 | 92 | debug(26, 3, "sslClientClosed: FD %d\n", fd); |
93 | /* we have been called from comm_close for the client side, so | |
94 | * just need to clean up the server side */ | |
f990cccc | 95 | protoUnregister(NULL, sslState->request, no_addr); |
30a4f2a8 | 96 | comm_close(sslState->server.fd); |
30a4f2a8 | 97 | } |
983061ed | 98 | |
b177367b | 99 | static void |
100 | sslStateFree(int fd, void *data) | |
983061ed | 101 | { |
b177367b | 102 | SslStateData *sslState = data; |
983061ed | 103 | debug(26, 3, "sslStateFree: FD %d, sslState=%p\n", fd, sslState); |
104 | if (sslState == NULL) | |
b177367b | 105 | return; |
983061ed | 106 | if (fd != sslState->server.fd) |
107 | fatal_dump("sslStateFree: FD mismatch!\n"); | |
4a8d63f1 | 108 | if (sslState->client.fd > -1) { |
109 | commSetSelect(sslState->client.fd, | |
110 | COMM_SELECT_READ, | |
111 | NULL, | |
112 | NULL, 0); | |
113 | } | |
983061ed | 114 | safe_free(sslState->server.buf); |
115 | safe_free(sslState->client.buf); | |
116 | xfree(sslState->url); | |
30a4f2a8 | 117 | requestUnlink(sslState->request); |
429fdbec | 118 | if (sslState->ip_lookup_pending) |
b69f7771 | 119 | ipcacheUnregister(sslState->host, sslState); |
983061ed | 120 | safe_free(sslState); |
983061ed | 121 | } |
122 | ||
983061ed | 123 | /* Read from server side and queue it for writing to the client */ |
b8d8561b | 124 | static void |
b177367b | 125 | sslReadServer(int fd, void *data) |
983061ed | 126 | { |
b177367b | 127 | SslStateData *sslState = data; |
983061ed | 128 | int len; |
30a4f2a8 | 129 | len = read(sslState->server.fd, sslState->server.buf, SQUID_TCP_SO_RCVBUF); |
4f92c80c | 130 | fd_bytes(sslState->server.fd, len, FD_READ); |
983061ed | 131 | debug(26, 5, "sslReadServer FD %d, read %d bytes\n", fd, len); |
132 | if (len < 0) { | |
881f7a6c | 133 | debug(50, 1, "sslReadServer: FD %d: read failure: %s\n", |
983061ed | 134 | sslState->server.fd, xstrerror()); |
0a0bf5db | 135 | if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { |
983061ed | 136 | /* reinstall handlers */ |
137 | /* XXX This may loop forever */ | |
b177367b | 138 | commSetSelect(sslState->server.fd, |
983061ed | 139 | COMM_SELECT_READ, |
b177367b | 140 | sslReadServer, |
cd1fb0eb | 141 | sslState, 0); |
983061ed | 142 | } else { |
30a4f2a8 | 143 | sslClose(sslState); |
983061ed | 144 | } |
145 | } else if (len == 0) { | |
146 | /* Connection closed; retrieval done. */ | |
30a4f2a8 | 147 | sslClose(sslState); |
983061ed | 148 | } else { |
149 | sslState->server.offset = 0; | |
150 | sslState->server.len = len; | |
4f92c80c | 151 | /* extend server read timeout */ |
152 | commSetTimeout(sslState->server.fd, Config.Timeout.read, NULL, NULL); | |
b177367b | 153 | commSetSelect(sslState->client.fd, |
983061ed | 154 | COMM_SELECT_WRITE, |
b177367b | 155 | sslWriteClient, |
cd1fb0eb | 156 | sslState, 0); |
983061ed | 157 | } |
158 | } | |
159 | ||
160 | /* Read from client side and queue it for writing to the server */ | |
b8d8561b | 161 | static void |
b177367b | 162 | sslReadClient(int fd, void *data) |
983061ed | 163 | { |
b177367b | 164 | SslStateData *sslState = data; |
983061ed | 165 | int len; |
30a4f2a8 | 166 | len = read(sslState->client.fd, sslState->client.buf, SQUID_TCP_SO_RCVBUF); |
4f92c80c | 167 | fd_bytes(sslState->client.fd, len, FD_READ); |
983061ed | 168 | debug(26, 5, "sslReadClient FD %d, read %d bytes\n", |
169 | sslState->client.fd, len); | |
170 | if (len < 0) { | |
881f7a6c | 171 | debug(50, 1, "sslReadClient: FD %d: read failure: %s\n", |
983061ed | 172 | fd, xstrerror()); |
0a0bf5db | 173 | if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { |
983061ed | 174 | /* reinstall handlers */ |
175 | /* XXX This may loop forever */ | |
b177367b | 176 | commSetSelect(sslState->client.fd, |
983061ed | 177 | COMM_SELECT_READ, |
b177367b | 178 | sslReadClient, |
cd1fb0eb | 179 | sslState, 0); |
983061ed | 180 | } else { |
30a4f2a8 | 181 | sslClose(sslState); |
983061ed | 182 | } |
183 | } else if (len == 0) { | |
184 | /* Connection closed; retrieval done. */ | |
30a4f2a8 | 185 | sslClose(sslState); |
983061ed | 186 | } else { |
187 | sslState->client.offset = 0; | |
188 | sslState->client.len = len; | |
b177367b | 189 | commSetSelect(sslState->server.fd, |
983061ed | 190 | COMM_SELECT_WRITE, |
b177367b | 191 | sslWriteServer, |
cd1fb0eb | 192 | sslState, 0); |
983061ed | 193 | } |
194 | } | |
195 | ||
196 | /* Writes data from the client buffer to the server side */ | |
b8d8561b | 197 | static void |
b177367b | 198 | sslWriteServer(int fd, void *data) |
983061ed | 199 | { |
b177367b | 200 | SslStateData *sslState = data; |
983061ed | 201 | int len; |
202 | len = write(sslState->server.fd, | |
203 | sslState->client.buf + sslState->client.offset, | |
204 | sslState->client.len - sslState->client.offset); | |
b69f7771 | 205 | fd_bytes(fd, len, FD_WRITE); |
983061ed | 206 | debug(26, 5, "sslWriteServer FD %d, wrote %d bytes\n", fd, len); |
207 | if (len < 0) { | |
0a0bf5db | 208 | if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { |
209 | commSetSelect(sslState->server.fd, | |
210 | COMM_SELECT_WRITE, | |
211 | sslWriteServer, | |
cd1fb0eb | 212 | sslState, 0); |
0a0bf5db | 213 | return; |
214 | } | |
881f7a6c | 215 | debug(50, 2, "sslWriteServer: FD %d: write failure: %s.\n", |
983061ed | 216 | sslState->server.fd, xstrerror()); |
30a4f2a8 | 217 | sslClose(sslState); |
983061ed | 218 | return; |
219 | } | |
220 | if ((sslState->client.offset += len) >= sslState->client.len) { | |
221 | /* Done writing, read more */ | |
b177367b | 222 | commSetSelect(sslState->client.fd, |
983061ed | 223 | COMM_SELECT_READ, |
b177367b | 224 | sslReadClient, |
cd1fb0eb | 225 | sslState, 0); |
983061ed | 226 | } else { |
227 | /* still have more to write */ | |
b177367b | 228 | commSetSelect(sslState->server.fd, |
983061ed | 229 | COMM_SELECT_WRITE, |
b177367b | 230 | sslWriteServer, |
cd1fb0eb | 231 | sslState, 0); |
983061ed | 232 | } |
233 | } | |
234 | ||
235 | /* Writes data from the server buffer to the client side */ | |
b8d8561b | 236 | static void |
b177367b | 237 | sslWriteClient(int fd, void *data) |
983061ed | 238 | { |
b177367b | 239 | SslStateData *sslState = data; |
983061ed | 240 | int len; |
241 | debug(26, 5, "sslWriteClient FD %d len=%d offset=%d\n", | |
242 | fd, | |
243 | sslState->server.len, | |
244 | sslState->server.offset); | |
245 | len = write(sslState->client.fd, | |
246 | sslState->server.buf + sslState->server.offset, | |
247 | sslState->server.len - sslState->server.offset); | |
b69f7771 | 248 | fd_bytes(fd, len, FD_WRITE); |
983061ed | 249 | debug(26, 5, "sslWriteClient FD %d, wrote %d bytes\n", fd, len); |
250 | if (len < 0) { | |
0a0bf5db | 251 | if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { |
252 | commSetSelect(sslState->client.fd, | |
253 | COMM_SELECT_WRITE, | |
254 | sslWriteClient, | |
cd1fb0eb | 255 | sslState, 0); |
0a0bf5db | 256 | return; |
257 | } | |
881f7a6c | 258 | debug(50, 2, "sslWriteClient: FD %d: write failure: %s.\n", |
983061ed | 259 | sslState->client.fd, xstrerror()); |
30a4f2a8 | 260 | sslClose(sslState); |
983061ed | 261 | return; |
262 | } | |
263 | if (sslState->size_ptr) | |
264 | *sslState->size_ptr += len; /* increment total object size */ | |
265 | if ((sslState->server.offset += len) >= sslState->server.len) { | |
266 | /* Done writing, read more */ | |
b177367b | 267 | commSetSelect(sslState->server.fd, |
983061ed | 268 | COMM_SELECT_READ, |
b177367b | 269 | sslReadServer, |
cd1fb0eb | 270 | sslState, 0); |
983061ed | 271 | } else { |
272 | /* still have more to write */ | |
b177367b | 273 | commSetSelect(sslState->client.fd, |
983061ed | 274 | COMM_SELECT_WRITE, |
b177367b | 275 | sslWriteClient, |
cd1fb0eb | 276 | sslState, 0); |
983061ed | 277 | } |
278 | } | |
279 | ||
b8d8561b | 280 | static void |
5c5783a2 | 281 | sslTimeout(int fd, void *data) |
983061ed | 282 | { |
b177367b | 283 | SslStateData *sslState = data; |
5c5783a2 | 284 | debug(26, 3, "sslTimeout: FD %d\n", fd); |
30a4f2a8 | 285 | sslClose(sslState); |
983061ed | 286 | } |
287 | ||
b8d8561b | 288 | static void |
b177367b | 289 | sslConnected(int fd, void *data) |
983061ed | 290 | { |
b177367b | 291 | SslStateData *sslState = data; |
983061ed | 292 | debug(26, 3, "sslConnected: FD %d sslState=%p\n", fd, sslState); |
293 | strcpy(sslState->server.buf, conn_established); | |
294 | sslState->server.len = strlen(conn_established); | |
295 | sslState->server.offset = 0; | |
5c5783a2 | 296 | commSetTimeout(sslState->server.fd, Config.Timeout.read, NULL, NULL); |
b177367b | 297 | commSetSelect(sslState->client.fd, |
983061ed | 298 | COMM_SELECT_WRITE, |
b177367b | 299 | sslWriteClient, |
cd1fb0eb | 300 | sslState, 0); |
b177367b | 301 | commSetSelect(sslState->client.fd, |
983061ed | 302 | COMM_SELECT_READ, |
b177367b | 303 | sslReadClient, |
cd1fb0eb | 304 | sslState, 0); |
983061ed | 305 | } |
306 | ||
b8d8561b | 307 | static void |
308 | sslErrorComplete(int fd, char *buf, int size, int errflag, void *sslState) | |
30a4f2a8 | 309 | { |
310 | safe_free(buf); | |
b2186d32 | 311 | if (sslState == NULL) { |
312 | debug_trap("sslErrorComplete: NULL sslState\n"); | |
313 | return; | |
314 | } | |
30a4f2a8 | 315 | sslClose(sslState); |
316 | } | |
317 | ||
983061ed | 318 | |
b8d8561b | 319 | static void |
fe4e214f | 320 | sslConnect(int fd, const ipcache_addrs * ia, void *data) |
983061ed | 321 | { |
b15fe823 | 322 | SslStateData *sslState = data; |
30a4f2a8 | 323 | request_t *request = sslState->request; |
30a4f2a8 | 324 | char *buf = NULL; |
429fdbec | 325 | sslState->ip_lookup_pending = 0; |
e5f6c5c2 | 326 | if (ia == NULL) { |
98ffb7e4 | 327 | debug(26, 4, "sslConnect: Unknown host: %s\n", sslState->host); |
30a4f2a8 | 328 | buf = squid_error_url(sslState->url, |
983061ed | 329 | request->method, |
330 | ERR_DNS_FAIL, | |
331 | fd_table[fd].ipaddr, | |
332 | 500, | |
333 | dns_error_message); | |
30a4f2a8 | 334 | comm_write(sslState->client.fd, |
335 | xstrdup(buf), | |
336 | strlen(buf), | |
30a4f2a8 | 337 | sslErrorComplete, |
cd1fb0eb | 338 | sslState, |
4a63c85f | 339 | xfree); |
b15fe823 | 340 | return; |
983061ed | 341 | } |
30a4f2a8 | 342 | debug(26, 5, "sslConnect: client=%d server=%d\n", |
983061ed | 343 | sslState->client.fd, |
344 | sslState->server.fd); | |
5c5783a2 | 345 | commSetTimeout(sslState->server.fd, |
4f92c80c | 346 | Config.Timeout.read, |
347 | sslTimeout, | |
348 | sslState); | |
e924600d | 349 | commConnectStart(fd, |
350 | sslState->host, | |
351 | sslState->port, | |
352 | sslConnectDone, | |
353 | sslState); | |
e5f6c5c2 | 354 | } |
355 | ||
356 | static void | |
357 | sslConnectDone(int fd, int status, void *data) | |
358 | { | |
359 | SslStateData *sslState = data; | |
360 | char *buf = NULL; | |
361 | if (status == COMM_ERROR) { | |
362 | buf = squid_error_url(sslState->url, | |
363 | sslState->request->method, | |
364 | ERR_CONNECT_FAIL, | |
365 | fd_table[fd].ipaddr, | |
366 | 500, | |
367 | xstrerror()); | |
368 | comm_write(sslState->client.fd, | |
369 | xstrdup(buf), | |
370 | strlen(buf), | |
e5f6c5c2 | 371 | sslErrorComplete, |
cd1fb0eb | 372 | sslState, |
e5f6c5c2 | 373 | xfree); |
374 | return; | |
983061ed | 375 | } |
b44c0fb4 | 376 | if (opt_no_ipcache) |
377 | ipcacheInvalidate(sslState->host); | |
93868820 | 378 | if (sslState->proxying) |
98ffb7e4 | 379 | sslProxyConnected(sslState->server.fd, sslState); |
380 | else | |
381 | sslConnected(sslState->server.fd, sslState); | |
983061ed | 382 | } |
30a4f2a8 | 383 | |
770f051d | 384 | void |
fe4e214f | 385 | sslStart(int fd, const char *url, request_t * request, char *mime_hdr, int *size_ptr) |
30a4f2a8 | 386 | { |
387 | /* Create state structure. */ | |
388 | SslStateData *sslState = NULL; | |
389 | int sock; | |
390 | char *buf = NULL; | |
30a4f2a8 | 391 | debug(26, 3, "sslStart: '%s %s'\n", |
392 | RequestMethodStr[request->method], url); | |
30a4f2a8 | 393 | /* Create socket. */ |
16b204c4 | 394 | sock = comm_open(SOCK_STREAM, |
395 | 0, | |
396 | Config.Addrs.tcp_outgoing, | |
397 | 0, | |
398 | COMM_NONBLOCKING, | |
399 | url); | |
30a4f2a8 | 400 | if (sock == COMM_ERROR) { |
401 | debug(26, 4, "sslStart: Failed because we're out of sockets.\n"); | |
402 | buf = squid_error_url(url, | |
403 | request->method, | |
404 | ERR_NO_FDS, | |
405 | fd_table[fd].ipaddr, | |
406 | 500, | |
407 | xstrerror()); | |
b2186d32 | 408 | comm_write(fd, |
30a4f2a8 | 409 | xstrdup(buf), |
410 | strlen(buf), | |
b2186d32 | 411 | NULL, |
412 | NULL, | |
4a63c85f | 413 | xfree); |
770f051d | 414 | return; |
30a4f2a8 | 415 | } |
416 | sslState = xcalloc(1, sizeof(SslStateData)); | |
417 | sslState->url = xstrdup(url); | |
418 | sslState->request = requestLink(request); | |
419 | sslState->mime_hdr = mime_hdr; | |
5c5783a2 | 420 | sslState->timeout = Config.Timeout.read; |
30a4f2a8 | 421 | sslState->size_ptr = size_ptr; |
422 | sslState->client.fd = fd; | |
423 | sslState->server.fd = sock; | |
424 | sslState->server.buf = xmalloc(SQUID_TCP_SO_RCVBUF); | |
425 | sslState->client.buf = xmalloc(SQUID_TCP_SO_RCVBUF); | |
426 | comm_add_close_handler(sslState->server.fd, | |
b177367b | 427 | sslStateFree, |
cd1fb0eb | 428 | sslState); |
30a4f2a8 | 429 | comm_add_close_handler(sslState->client.fd, |
b177367b | 430 | sslClientClosed, |
cd1fb0eb | 431 | sslState); |
5c5783a2 | 432 | commSetTimeout(sslState->client.fd, |
4f92c80c | 433 | Config.Timeout.lifetime, |
434 | sslTimeout, | |
435 | sslState); | |
b6c0e933 | 436 | peerSelect(request, |
641941c0 | 437 | NULL, |
b6c0e933 | 438 | sslPeerSelectComplete, |
439 | sslPeerSelectFail, | |
440 | sslState); | |
30a4f2a8 | 441 | } |
98ffb7e4 | 442 | |
b8d8561b | 443 | static void |
b177367b | 444 | sslProxyConnected(int fd, void *data) |
98ffb7e4 | 445 | { |
b177367b | 446 | SslStateData *sslState = data; |
98ffb7e4 | 447 | debug(26, 3, "sslProxyConnected: FD %d sslState=%p\n", fd, sslState); |
448 | sprintf(sslState->client.buf, "CONNECT %s HTTP/1.0\r\n\r\n", sslState->url); | |
449 | debug(26, 3, "sslProxyConnected: Sending 'CONNECT %s HTTP/1.0'\n", sslState->url); | |
450 | sslState->client.len = strlen(sslState->client.buf); | |
451 | sslState->client.offset = 0; | |
b177367b | 452 | commSetSelect(sslState->server.fd, |
98ffb7e4 | 453 | COMM_SELECT_WRITE, |
b177367b | 454 | sslWriteServer, |
cd1fb0eb | 455 | sslState, 0); |
5c5783a2 | 456 | commSetTimeout(fd, Config.Timeout.read, NULL, NULL); |
b177367b | 457 | commSetSelect(sslState->server.fd, |
98ffb7e4 | 458 | COMM_SELECT_READ, |
b177367b | 459 | sslReadServer, |
cd1fb0eb | 460 | sslState, 0); |
98ffb7e4 | 461 | } |
33ea9fff | 462 | |
33ea9fff | 463 | static void |
641941c0 | 464 | sslPeerSelectComplete(peer * p, void *data) |
33ea9fff | 465 | { |
466 | SslStateData *sslState = data; | |
467 | request_t *request = sslState->request; | |
deb79f06 | 468 | peer *g = NULL; |
b6c0e933 | 469 | sslState->proxying = p ? 1 : 0; |
470 | sslState->host = p ? p->host : request->host; | |
471 | if (p == NULL) { | |
b3b64e58 | 472 | sslState->port = request->port; |
b6c0e933 | 473 | } else if (p->http_port != 0) { |
474 | sslState->port = p->http_port; | |
475 | } else if ((g = neighborFindByName(p->host))) { | |
b3b64e58 | 476 | sslState->port = g->http_port; |
33ea9fff | 477 | } else { |
b3b64e58 | 478 | sslState->port = CACHE_HTTP_PORT; |
33ea9fff | 479 | } |
429fdbec | 480 | sslState->ip_lookup_pending = 1; |
33ea9fff | 481 | ipcache_nbgethostbyname(sslState->host, |
482 | sslState->server.fd, | |
483 | sslConnect, | |
484 | sslState); | |
485 | } | |
b6c0e933 | 486 | |
487 | static void | |
641941c0 | 488 | sslPeerSelectFail(peer * p, void *data) |
b6c0e933 | 489 | { |
490 | SslStateData *sslState = data; | |
491 | squid_error_request(sslState->url, ERR_CANNOT_FETCH, 400); | |
492 | sslClose(sslState); | |
493 | } |