]> git.ipfire.org Git - thirdparty/squid.git/blame - src/tunnel.cc
merge changes from SQUID_2_3 branch
[thirdparty/squid.git] / src / tunnel.cc
CommitLineData
95d659f0 1
983061ed 2/*
7e3ce7b9 3 * $Id: tunnel.cc,v 1.101 1999/12/30 17:36:51 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/
e25c139f 9 * ----------------------------------------------------------
30a4f2a8 10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
e25c139f 13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
30a4f2a8 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
983061ed 34 */
983061ed 35
30a4f2a8 36#include "squid.h"
983061ed 37
38typedef struct {
39 char *url;
98ffb7e4 40 char *host; /* either request->host or proxy host */
41 u_short port;
983061ed 42 request_t *request;
64d8034e 43 FwdServer *servers;
983061ed 44 struct {
45 int fd;
46 int len;
983061ed 47 char *buf;
48 } client, server;
88738790 49 size_t *size_ptr; /* pointer to size in an ConnStateData for logging */
59715b38 50#if DELAY_POOLS
51 delay_id delay_id;
52#endif
983061ed 53} SslStateData;
54
0ee4272b 55static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n";
983061ed 56
54cff85f 57static CNCB sslConnectDone;
58static ERCB sslErrorComplete;
adb78bd4 59static PF sslServerClosed;
54cff85f 60static PF sslClientClosed;
61static PF sslReadClient;
62static PF sslReadServer;
5c5783a2 63static PF sslTimeout;
54cff85f 64static PF sslWriteClient;
65static PF sslWriteServer;
66static PSC sslPeerSelectComplete;
adb78bd4 67static void sslStateFree(SslStateData * sslState);
f5b8bbc4 68static void sslConnected(int fd, void *);
69static void sslProxyConnected(int fd, void *);
adb78bd4 70static void sslSetSelect(SslStateData * sslState);
447e176b 71#if DELAY_POOLS
72static DEFER sslDeferServerRead;
73#endif
30a4f2a8 74
b8d8561b 75static void
adb78bd4 76sslServerClosed(int fd, void *data)
30a4f2a8 77{
adb78bd4 78 SslStateData *sslState = data;
79 debug(26, 3) ("sslServerClosed: FD %d\n", fd);
80 assert(fd == sslState->server.fd);
81 sslState->server.fd = -1;
82 if (sslState->client.fd == -1)
83 sslStateFree(sslState);
30a4f2a8 84}
85
b177367b 86static void
87sslClientClosed(int fd, void *data)
30a4f2a8 88{
b177367b 89 SslStateData *sslState = data;
a3d5953d 90 debug(26, 3) ("sslClientClosed: FD %d\n", fd);
adb78bd4 91 assert(fd == sslState->client.fd);
92 sslState->client.fd = -1;
93 if (sslState->server.fd == -1)
94 sslStateFree(sslState);
30a4f2a8 95}
983061ed 96
b177367b 97static void
adb78bd4 98sslStateFree(SslStateData * sslState)
983061ed 99{
adb78bd4 100 debug(26, 3) ("sslStateFree: sslState=%p\n", sslState);
101 assert(sslState != NULL);
102 assert(sslState->client.fd == -1);
103 assert(sslState->server.fd == -1);
983061ed 104 safe_free(sslState->server.buf);
105 safe_free(sslState->client.buf);
adb78bd4 106 safe_free(sslState->url);
64d8034e 107 fwdServersFree(&sslState->servers);
adb78bd4 108 sslState->host = NULL;
30a4f2a8 109 requestUnlink(sslState->request);
7dd44885 110 sslState->request = NULL;
b6a2f15e 111#if DELAY_POOLS
112 delayUnregisterDelayIdPtr(&sslState->delay_id);
113#endif
7dd44885 114 cbdataFree(sslState);
983061ed 115}
116
447e176b 117#if DELAY_POOLS
118static int
119sslDeferServerRead(int fdnotused, void *data)
120{
59715b38 121 SslStateData *s = data;
7e3ce7b9 122 int i = delayBytesWanted(s->delay_id, 0, INT_MAX);
123 if (i == INT_MAX)
124 return 0;
125 if (i == 0)
126 return 1;
127 return -1;
447e176b 128}
129#endif
130
adb78bd4 131static void
132sslSetSelect(SslStateData * sslState)
133{
447e176b 134 size_t read_sz = SQUID_TCP_SO_RCVBUF;
adb78bd4 135 assert(sslState->server.fd > -1 || sslState->client.fd > -1);
136 if (sslState->client.fd > -1) {
137 if (sslState->server.len > 0) {
138 commSetSelect(sslState->client.fd,
139 COMM_SELECT_WRITE,
140 sslWriteClient,
141 sslState,
142 0);
143 }
447e176b 144 if (sslState->client.len < read_sz) {
adb78bd4 145 commSetSelect(sslState->client.fd,
146 COMM_SELECT_READ,
147 sslReadClient,
148 sslState,
149 Config.Timeout.read);
150 }
151 } else if (sslState->client.len == 0) {
152 comm_close(sslState->server.fd);
153 }
154 if (sslState->server.fd > -1) {
155 if (sslState->client.len > 0) {
156 commSetSelect(sslState->server.fd,
157 COMM_SELECT_WRITE,
158 sslWriteServer,
159 sslState,
160 0);
161 }
447e176b 162#if DELAY_POOLS
7e3ce7b9 163 /*
164 * If this was allowed to return 0, there would be a possibility
e82d6d21 165 * of the socket becoming "hung" with data accumulating but no
166 * write handler (server.len==0) and no read handler (!(0<0)) and
167 * no data flowing in the other direction. Hence the argument of
168 * 1 as min.
169 */
59715b38 170 read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz);
447e176b 171#endif
172 if (sslState->server.len < read_sz) {
adb78bd4 173 /* Have room to read more */
174 commSetSelect(sslState->server.fd,
175 COMM_SELECT_READ,
176 sslReadServer,
177 sslState,
178 Config.Timeout.read);
179 }
180 } else if (sslState->client.fd == -1) {
181 /* client already closed, nothing more to do */
182 } else if (sslState->server.len == 0) {
183 comm_close(sslState->client.fd);
184 }
185}
186
983061ed 187/* Read from server side and queue it for writing to the client */
b8d8561b 188static void
b177367b 189sslReadServer(int fd, void *data)
983061ed 190{
b177367b 191 SslStateData *sslState = data;
983061ed 192 int len;
447e176b 193 size_t read_sz = SQUID_TCP_SO_RCVBUF - sslState->server.len;
adb78bd4 194 assert(fd == sslState->server.fd);
195 debug(26, 3) ("sslReadServer: FD %d, reading %d bytes at offset %d\n",
447e176b 196 fd, read_sz, sslState->server.len);
197 errno = 0;
198#if DELAY_POOLS
59715b38 199 read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz);
447e176b 200#endif
886f2785 201 Counter.syscalls.sock.reads++;
447e176b 202 len = read(fd, sslState->server.buf + sslState->server.len, read_sz);
adb78bd4 203 debug(26, 3) ("sslReadServer: FD %d, read %d bytes\n", fd, len);
ee1679df 204 if (len > 0) {
adb78bd4 205 fd_bytes(fd, len, FD_READ);
447e176b 206#if DELAY_POOLS
59715b38 207 delayBytesIn(sslState->delay_id, len);
447e176b 208#endif
a0f32775 209 kb_incr(&Counter.server.all.kbytes_in, len);
210 kb_incr(&Counter.server.other.kbytes_in, len);
adb78bd4 211 sslState->server.len += len;
ee1679df 212 }
adb78bd4 213 cbdataLock(sslState);
983061ed 214 if (len < 0) {
9bc73deb 215 debug(50, ignoreErrno(errno) ? 3 : 1)
216 ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror());
adb78bd4 217 if (!ignoreErrno(errno))
218 comm_close(fd);
983061ed 219 } else if (len == 0) {
adb78bd4 220 comm_close(sslState->server.fd);
983061ed 221 }
adb78bd4 222 if (cbdataValid(sslState))
223 sslSetSelect(sslState);
224 cbdataUnlock(sslState);
983061ed 225}
226
227/* Read from client side and queue it for writing to the server */
b8d8561b 228static void
b177367b 229sslReadClient(int fd, void *data)
983061ed 230{
b177367b 231 SslStateData *sslState = data;
983061ed 232 int len;
adb78bd4 233 assert(fd == sslState->client.fd);
234 debug(26, 3) ("sslReadClient: FD %d, reading %d bytes at offset %d\n",
235 fd, SQUID_TCP_SO_RCVBUF - sslState->client.len,
236 sslState->client.len);
886f2785 237 Counter.syscalls.sock.reads++;
adb78bd4 238 len = read(fd,
239 sslState->client.buf + sslState->client.len,
240 SQUID_TCP_SO_RCVBUF - sslState->client.len);
241 debug(26, 3) ("sslReadClient: FD %d, read %d bytes\n", fd, len);
ee1679df 242 if (len > 0) {
adb78bd4 243 fd_bytes(fd, len, FD_READ);
ee1679df 244 kb_incr(&Counter.client_http.kbytes_in, len);
adb78bd4 245 sslState->client.len += len;
ee1679df 246 }
adb78bd4 247 cbdataLock(sslState);
983061ed 248 if (len < 0) {
eb824054 249 debug(50, ECONNRESET == errno ? 3 : 1) ("sslReadClient: FD %d: read failure: %s\n",
983061ed 250 fd, xstrerror());
adb78bd4 251 if (!ignoreErrno(errno))
252 comm_close(fd);
983061ed 253 } else if (len == 0) {
adb78bd4 254 comm_close(fd);
983061ed 255 }
adb78bd4 256 if (cbdataValid(sslState))
257 sslSetSelect(sslState);
258 cbdataUnlock(sslState);
983061ed 259}
260
261/* Writes data from the client buffer to the server side */
b8d8561b 262static void
b177367b 263sslWriteServer(int fd, void *data)
983061ed 264{
b177367b 265 SslStateData *sslState = data;
983061ed 266 int len;
adb78bd4 267 assert(fd == sslState->server.fd);
268 debug(26, 3) ("sslWriteServer: FD %d, %d bytes to write\n",
269 fd, sslState->client.len);
886f2785 270 Counter.syscalls.sock.writes++;
adb78bd4 271 len = write(fd,
272 sslState->client.buf,
273 sslState->client.len);
274 debug(26, 3) ("sslWriteServer: FD %d, %d bytes written\n", fd, len);
ee1679df 275 if (len > 0) {
adb78bd4 276 fd_bytes(fd, len, FD_WRITE);
a0f32775 277 kb_incr(&Counter.server.all.kbytes_out, len);
278 kb_incr(&Counter.server.other.kbytes_out, len);
adb78bd4 279 assert(len <= sslState->client.len);
280 sslState->client.len -= len;
281 if (sslState->client.len > 0) {
282 /* we didn't write the whole thing */
283 xmemmove(sslState->client.buf,
284 sslState->client.buf + len,
285 sslState->client.len);
0a0bf5db 286 }
983061ed 287 }
adb78bd4 288 cbdataLock(sslState);
289 if (len < 0) {
9bc73deb 290 debug(50, ignoreErrno(errno) ? 3 : 1)
291 ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror());
adb78bd4 292 if (!ignoreErrno(errno))
293 comm_close(fd);
983061ed 294 }
adb78bd4 295 if (cbdataValid(sslState))
296 sslSetSelect(sslState);
297 cbdataUnlock(sslState);
983061ed 298}
299
300/* Writes data from the server buffer to the client side */
b8d8561b 301static void
b177367b 302sslWriteClient(int fd, void *data)
983061ed 303{
b177367b 304 SslStateData *sslState = data;
983061ed 305 int len;
adb78bd4 306 assert(fd == sslState->client.fd);
307 debug(26, 3) ("sslWriteClient: FD %d, %d bytes to write\n",
308 fd, sslState->server.len);
886f2785 309 Counter.syscalls.sock.writes++;
adb78bd4 310 len = write(fd,
311 sslState->server.buf,
312 sslState->server.len);
313 debug(26, 3) ("sslWriteClient: FD %d, %d bytes written\n", fd, len);
ee1679df 314 if (len > 0) {
adb78bd4 315 fd_bytes(fd, len, FD_WRITE);
ee1679df 316 kb_incr(&Counter.client_http.kbytes_out, len);
adb78bd4 317 assert(len <= sslState->server.len);
318 sslState->server.len -= len;
319 /* increment total object size */
320 if (sslState->size_ptr)
321 *sslState->size_ptr += len;
322 if (sslState->server.len > 0) {
323 /* we didn't write the whole thing */
324 xmemmove(sslState->server.buf,
325 sslState->server.buf + len,
326 sslState->server.len);
0a0bf5db 327 }
983061ed 328 }
adb78bd4 329 cbdataLock(sslState);
330 if (len < 0) {
9bc73deb 331 debug(50, ignoreErrno(errno) ? 3 : 1)
332 ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror());
adb78bd4 333 if (!ignoreErrno(errno))
334 comm_close(fd);
983061ed 335 }
adb78bd4 336 if (cbdataValid(sslState))
337 sslSetSelect(sslState);
338 cbdataUnlock(sslState);
983061ed 339}
340
b8d8561b 341static void
5c5783a2 342sslTimeout(int fd, void *data)
983061ed 343{
b177367b 344 SslStateData *sslState = data;
a3d5953d 345 debug(26, 3) ("sslTimeout: FD %d\n", fd);
adb78bd4 346 if (sslState->client.fd > -1)
347 comm_close(sslState->client.fd);
348 if (sslState->server.fd > -1)
349 comm_close(sslState->server.fd);
983061ed 350}
351
b8d8561b 352static void
b177367b 353sslConnected(int fd, void *data)
983061ed 354{
b177367b 355 SslStateData *sslState = data;
a3d5953d 356 debug(26, 3) ("sslConnected: FD %d sslState=%p\n", fd, sslState);
54cff85f 357 xstrncpy(sslState->server.buf, conn_established, SQUID_TCP_SO_RCVBUF);
983061ed 358 sslState->server.len = strlen(conn_established);
adb78bd4 359 sslSetSelect(sslState);
983061ed 360}
361
b8d8561b 362static void
adb78bd4 363sslErrorComplete(int fdnotused, void *data, size_t sizenotused)
30a4f2a8 364{
adb78bd4 365 SslStateData *sslState = data;
9b312a19 366 assert(sslState != NULL);
adb78bd4 367 if (sslState->client.fd > -1)
368 comm_close(sslState->client.fd);
369 if (sslState->server.fd > -1)
370 comm_close(sslState->server.fd);
30a4f2a8 371}
372
983061ed 373
b8d8561b 374static void
79d39a72 375sslConnectDone(int fdnotused, int status, void *data)
983061ed 376{
b15fe823 377 SslStateData *sslState = data;
30a4f2a8 378 request_t *request = sslState->request;
9b312a19 379 ErrorState *err = NULL;
edeb28fd 380 if (status == COMM_ERR_DNS) {
a3d5953d 381 debug(26, 4) ("sslConnect: Unknown host: %s\n", sslState->host);
fe40a877 382 err = errorCon(ERR_DNS_FAIL, HTTP_NOT_FOUND);
9b312a19 383 err->request = requestLink(request);
384 err->dnsserver_msg = xstrdup(dns_error_message);
385 err->callback = sslErrorComplete;
386 err->callback_data = sslState;
387 errorSend(sslState->client.fd, err);
edeb28fd 388 } else if (status != COMM_OK) {
fe40a877 389 err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
c45ed9ad 390 err->xerrno = errno;
9b312a19 391 err->host = xstrdup(sslState->host);
392 err->port = sslState->port;
393 err->request = requestLink(request);
394 err->callback = sslErrorComplete;
395 err->callback_data = sslState;
396 errorSend(sslState->client.fd, err);
fe40a877 397 } else {
64d8034e 398 if (sslState->servers->peer)
fe40a877 399 sslProxyConnected(sslState->server.fd, sslState);
4e3f29eb 400 else
fe40a877 401 sslConnected(sslState->server.fd, sslState);
1afe05c5 402 commSetTimeout(sslState->server.fd,
403 Config.Timeout.read,
404 sslTimeout,
405 sslState);
447e176b 406#if DELAY_POOLS
59715b38 407 commSetDefer(sslState->server.fd, sslDeferServerRead, sslState);
447e176b 408#endif
983061ed 409 }
983061ed 410}
30a4f2a8 411
770f051d 412void
9b312a19 413sslStart(int fd, const char *url, request_t * request, size_t * size_ptr)
30a4f2a8 414{
415 /* Create state structure. */
416 SslStateData *sslState = NULL;
417 int sock;
9b312a19 418 ErrorState *err = NULL;
a3d5953d 419 debug(26, 3) ("sslStart: '%s %s'\n",
30a4f2a8 420 RequestMethodStr[request->method], url);
a0f32775 421 Counter.server.all.requests++;
422 Counter.server.other.requests++;
30a4f2a8 423 /* Create socket. */
16b204c4 424 sock = comm_open(SOCK_STREAM,
425 0,
426 Config.Addrs.tcp_outgoing,
427 0,
428 COMM_NONBLOCKING,
429 url);
30a4f2a8 430 if (sock == COMM_ERROR) {
a3d5953d 431 debug(26, 4) ("sslStart: Failed because we're out of sockets.\n");
fe40a877 432 err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
c45ed9ad 433 err->xerrno = errno;
9b312a19 434 err->request = requestLink(request);
435 errorSend(fd, err);
770f051d 436 return;
30a4f2a8 437 }
438 sslState = xcalloc(1, sizeof(SslStateData));
db1cd23c 439 cbdataAdd(sslState, cbdataXfree, 0);
59715b38 440#if DELAY_POOLS
441 sslState->delay_id = delayClient(request);
b6a2f15e 442 delayRegisterDelayIdPtr(&sslState->delay_id);
59715b38 443#endif
30a4f2a8 444 sslState->url = xstrdup(url);
445 sslState->request = requestLink(request);
30a4f2a8 446 sslState->size_ptr = size_ptr;
447 sslState->client.fd = fd;
448 sslState->server.fd = sock;
449 sslState->server.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
450 sslState->client.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
451 comm_add_close_handler(sslState->server.fd,
adb78bd4 452 sslServerClosed,
cd1fb0eb 453 sslState);
30a4f2a8 454 comm_add_close_handler(sslState->client.fd,
b177367b 455 sslClientClosed,
cd1fb0eb 456 sslState);
5c5783a2 457 commSetTimeout(sslState->client.fd,
4f92c80c 458 Config.Timeout.lifetime,
459 sslTimeout,
460 sslState);
cf1edeae 461 commSetTimeout(sslState->server.fd,
462 Config.Timeout.connect,
463 sslTimeout,
464 sslState);
b6c0e933 465 peerSelect(request,
641941c0 466 NULL,
b6c0e933 467 sslPeerSelectComplete,
b6c0e933 468 sslState);
adb78bd4 469 /*
470 * Disable the client read handler until peer selection is complete
471 * Take control away from client_side.c.
472 */
473 commSetSelect(sslState->client.fd, COMM_SELECT_READ, NULL, NULL, 0);
30a4f2a8 474}
98ffb7e4 475
b8d8561b 476static void
b177367b 477sslProxyConnected(int fd, void *data)
98ffb7e4 478{
b177367b 479 SslStateData *sslState = data;
e1e72f06 480 MemBuf mb;
481 HttpHeader hdr_out;
482 Packer p;
b4b5fd95 483 http_state_flags flags;
a3d5953d 484 debug(26, 3) ("sslProxyConnected: FD %d sslState=%p\n", fd, sslState);
b4b5fd95 485 memset(&flags, '\0', sizeof(flags));
e1e72f06 486 memBufDefInit(&mb);
487 memBufPrintf(&mb, "CONNECT %s HTTP/1.0\r\n", sslState->url);
488 httpBuildRequestHeader(sslState->request,
489 sslState->request,
5999b776 490 NULL, /* StoreEntry */
e1e72f06 491 &hdr_out,
492 sslState->client.fd,
b4b5fd95 493 flags); /* flags */
e1e72f06 494 packerToMemInit(&p, &mb);
495 httpHeaderPackInto(&hdr_out, &p);
496 httpHeaderClean(&hdr_out);
497 packerClean(&p);
498 memBufAppend(&mb, "\r\n", 2);
499 xstrncpy(sslState->client.buf, mb.buf, SQUID_TCP_SO_RCVBUF);
500 debug(26, 3) ("sslProxyConnected: Sending {%s}\n", sslState->client.buf);
501 sslState->client.len = mb.size;
e1e72f06 502 memBufClean(&mb);
86cf9987 503 commSetTimeout(sslState->server.fd,
504 Config.Timeout.read,
505 sslTimeout,
506 sslState);
adb78bd4 507 sslSetSelect(sslState);
98ffb7e4 508}
33ea9fff 509
33ea9fff 510static void
db1cd23c 511sslPeerSelectComplete(FwdServer * fs, void *data)
33ea9fff 512{
513 SslStateData *sslState = data;
514 request_t *request = sslState->request;
deb79f06 515 peer *g = NULL;
db1cd23c 516 if (fs == NULL) {
517 ErrorState *err;
518 err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
519 err->request = requestLink(sslState->request);
520 err->callback = sslErrorComplete;
521 err->callback_data = sslState;
522 errorSend(sslState->client.fd, err);
523 return;
524 }
64d8034e 525 sslState->servers = fs;
db1cd23c 526 sslState->host = fs->peer ? fs->peer->host : request->host;
527 if (fs->peer == NULL) {
b3b64e58 528 sslState->port = request->port;
db1cd23c 529 } else if (fs->peer->http_port != 0) {
530 sslState->port = fs->peer->http_port;
531 } else if ((g = peerFindByName(fs->peer->host))) {
b3b64e58 532 sslState->port = g->http_port;
33ea9fff 533 } else {
b3b64e58 534 sslState->port = CACHE_HTTP_PORT;
33ea9fff 535 }
1f38f50a 536 if (fs->peer) {
537 sslState->request->peer_login = fs->peer->login;
538 sslState->request->flags.proxying = 1;
539 } else {
540 sslState->request->flags.proxying = 0;
541 }
59715b38 542#if DELAY_POOLS
543 /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
1ecaa0a0 544 if (g && g->options.no_delay && sslState->delay_id) {
545 delayUnregisterDelayIdPtr(&sslState->delay_id);
59715b38 546 sslState->delay_id = 0;
1ecaa0a0 547 }
59715b38 548#endif
64d8034e 549 hierarchyNote(&sslState->request->hier,
550 fs->peer ? fs->code : DIRECT,
551 sslState->host);
edeb28fd 552 commConnectStart(sslState->server.fd,
553 sslState->host,
554 sslState->port,
555 sslConnectDone,
33ea9fff 556 sslState);
557}