]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl.cc
Avoid NULL http->entry pointer in clientBuildReplyHeader().
[thirdparty/squid.git] / src / ssl.cc
CommitLineData
95d659f0 1
983061ed 2/*
2b6662ba 3 * $Id: ssl.cc,v 1.111 2001/01/12 00:37:21 wessels Exp $
983061ed 4 *
30a4f2a8 5 * DEBUG: section 26 Secure Sockets Layer Proxy
6 * AUTHOR: Duane Wessels
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
30a4f2a8 10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see 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 */
974ba0ee 50 int *status_ptr; /* pointer to status for logging */
59715b38 51#if DELAY_POOLS
52 delay_id delay_id;
53#endif
983061ed 54} SslStateData;
55
0ee4272b 56static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n";
983061ed 57
54cff85f 58static CNCB sslConnectDone;
59static ERCB sslErrorComplete;
adb78bd4 60static PF sslServerClosed;
54cff85f 61static PF sslClientClosed;
62static PF sslReadClient;
63static PF sslReadServer;
5c5783a2 64static PF sslTimeout;
54cff85f 65static PF sslWriteClient;
66static PF sslWriteServer;
67static PSC sslPeerSelectComplete;
adb78bd4 68static void sslStateFree(SslStateData * sslState);
f5b8bbc4 69static void sslConnected(int fd, void *);
70static void sslProxyConnected(int fd, void *);
adb78bd4 71static void sslSetSelect(SslStateData * sslState);
447e176b 72#if DELAY_POOLS
73static DEFER sslDeferServerRead;
74#endif
30a4f2a8 75
b8d8561b 76static void
adb78bd4 77sslServerClosed(int fd, void *data)
30a4f2a8 78{
adb78bd4 79 SslStateData *sslState = data;
80 debug(26, 3) ("sslServerClosed: FD %d\n", fd);
81 assert(fd == sslState->server.fd);
82 sslState->server.fd = -1;
83 if (sslState->client.fd == -1)
84 sslStateFree(sslState);
30a4f2a8 85}
86
b177367b 87static void
88sslClientClosed(int fd, void *data)
30a4f2a8 89{
b177367b 90 SslStateData *sslState = data;
a3d5953d 91 debug(26, 3) ("sslClientClosed: FD %d\n", fd);
adb78bd4 92 assert(fd == sslState->client.fd);
93 sslState->client.fd = -1;
94 if (sslState->server.fd == -1)
95 sslStateFree(sslState);
30a4f2a8 96}
983061ed 97
b177367b 98static void
adb78bd4 99sslStateFree(SslStateData * sslState)
983061ed 100{
adb78bd4 101 debug(26, 3) ("sslStateFree: sslState=%p\n", sslState);
102 assert(sslState != NULL);
103 assert(sslState->client.fd == -1);
104 assert(sslState->server.fd == -1);
983061ed 105 safe_free(sslState->server.buf);
106 safe_free(sslState->client.buf);
adb78bd4 107 safe_free(sslState->url);
64d8034e 108 fwdServersFree(&sslState->servers);
adb78bd4 109 sslState->host = NULL;
30a4f2a8 110 requestUnlink(sslState->request);
7dd44885 111 sslState->request = NULL;
b6a2f15e 112#if DELAY_POOLS
113 delayUnregisterDelayIdPtr(&sslState->delay_id);
114#endif
7dd44885 115 cbdataFree(sslState);
983061ed 116}
117
447e176b 118#if DELAY_POOLS
119static int
120sslDeferServerRead(int fdnotused, void *data)
121{
59715b38 122 SslStateData *s = data;
7e3ce7b9 123 int i = delayBytesWanted(s->delay_id, 0, INT_MAX);
124 if (i == INT_MAX)
125 return 0;
126 if (i == 0)
127 return 1;
128 return -1;
447e176b 129}
130#endif
131
adb78bd4 132static void
133sslSetSelect(SslStateData * sslState)
134{
447e176b 135 size_t read_sz = SQUID_TCP_SO_RCVBUF;
adb78bd4 136 assert(sslState->server.fd > -1 || sslState->client.fd > -1);
137 if (sslState->client.fd > -1) {
138 if (sslState->server.len > 0) {
139 commSetSelect(sslState->client.fd,
140 COMM_SELECT_WRITE,
141 sslWriteClient,
142 sslState,
143 0);
144 }
447e176b 145 if (sslState->client.len < read_sz) {
adb78bd4 146 commSetSelect(sslState->client.fd,
147 COMM_SELECT_READ,
148 sslReadClient,
149 sslState,
150 Config.Timeout.read);
151 }
152 } else if (sslState->client.len == 0) {
153 comm_close(sslState->server.fd);
154 }
155 if (sslState->server.fd > -1) {
156 if (sslState->client.len > 0) {
157 commSetSelect(sslState->server.fd,
158 COMM_SELECT_WRITE,
159 sslWriteServer,
160 sslState,
161 0);
162 }
447e176b 163#if DELAY_POOLS
7e3ce7b9 164 /*
165 * If this was allowed to return 0, there would be a possibility
e82d6d21 166 * of the socket becoming "hung" with data accumulating but no
167 * write handler (server.len==0) and no read handler (!(0<0)) and
168 * no data flowing in the other direction. Hence the argument of
169 * 1 as min.
170 */
59715b38 171 read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz);
447e176b 172#endif
173 if (sslState->server.len < read_sz) {
adb78bd4 174 /* Have room to read more */
175 commSetSelect(sslState->server.fd,
176 COMM_SELECT_READ,
177 sslReadServer,
178 sslState,
179 Config.Timeout.read);
180 }
181 } else if (sslState->client.fd == -1) {
182 /* client already closed, nothing more to do */
183 } else if (sslState->server.len == 0) {
184 comm_close(sslState->client.fd);
185 }
186}
187
983061ed 188/* Read from server side and queue it for writing to the client */
b8d8561b 189static void
b177367b 190sslReadServer(int fd, void *data)
983061ed 191{
b177367b 192 SslStateData *sslState = data;
983061ed 193 int len;
447e176b 194 size_t read_sz = SQUID_TCP_SO_RCVBUF - sslState->server.len;
adb78bd4 195 assert(fd == sslState->server.fd);
196 debug(26, 3) ("sslReadServer: FD %d, reading %d bytes at offset %d\n",
447e176b 197 fd, read_sz, sslState->server.len);
198 errno = 0;
199#if DELAY_POOLS
59715b38 200 read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz);
447e176b 201#endif
83704487 202 statCounter.syscalls.sock.reads++;
447e176b 203 len = read(fd, sslState->server.buf + sslState->server.len, read_sz);
adb78bd4 204 debug(26, 3) ("sslReadServer: FD %d, read %d bytes\n", fd, len);
ee1679df 205 if (len > 0) {
adb78bd4 206 fd_bytes(fd, len, FD_READ);
447e176b 207#if DELAY_POOLS
59715b38 208 delayBytesIn(sslState->delay_id, len);
447e176b 209#endif
83704487 210 kb_incr(&statCounter.server.all.kbytes_in, len);
211 kb_incr(&statCounter.server.other.kbytes_in, len);
adb78bd4 212 sslState->server.len += len;
ee1679df 213 }
adb78bd4 214 cbdataLock(sslState);
983061ed 215 if (len < 0) {
9bc73deb 216 debug(50, ignoreErrno(errno) ? 3 : 1)
217 ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror());
adb78bd4 218 if (!ignoreErrno(errno))
219 comm_close(fd);
983061ed 220 } else if (len == 0) {
adb78bd4 221 comm_close(sslState->server.fd);
983061ed 222 }
adb78bd4 223 if (cbdataValid(sslState))
224 sslSetSelect(sslState);
225 cbdataUnlock(sslState);
983061ed 226}
227
228/* Read from client side and queue it for writing to the server */
b8d8561b 229static void
b177367b 230sslReadClient(int fd, void *data)
983061ed 231{
b177367b 232 SslStateData *sslState = data;
983061ed 233 int len;
adb78bd4 234 assert(fd == sslState->client.fd);
235 debug(26, 3) ("sslReadClient: FD %d, reading %d bytes at offset %d\n",
236 fd, SQUID_TCP_SO_RCVBUF - sslState->client.len,
237 sslState->client.len);
83704487 238 statCounter.syscalls.sock.reads++;
adb78bd4 239 len = read(fd,
240 sslState->client.buf + sslState->client.len,
241 SQUID_TCP_SO_RCVBUF - sslState->client.len);
242 debug(26, 3) ("sslReadClient: FD %d, read %d bytes\n", fd, len);
ee1679df 243 if (len > 0) {
adb78bd4 244 fd_bytes(fd, len, FD_READ);
83704487 245 kb_incr(&statCounter.client_http.kbytes_in, len);
adb78bd4 246 sslState->client.len += len;
ee1679df 247 }
adb78bd4 248 cbdataLock(sslState);
983061ed 249 if (len < 0) {
7e0453ea 250 int level = 1;
251#ifdef ECONNRESET
252 if (errno == ECONNRESET)
253 level = 2;
254#endif
255 if (ignoreErrno(errno))
256 level = 3;
257 debug(50, level) ("sslReadClient: FD %d: read failure: %s\n",
983061ed 258 fd, xstrerror());
adb78bd4 259 if (!ignoreErrno(errno))
260 comm_close(fd);
983061ed 261 } else if (len == 0) {
adb78bd4 262 comm_close(fd);
983061ed 263 }
adb78bd4 264 if (cbdataValid(sslState))
265 sslSetSelect(sslState);
266 cbdataUnlock(sslState);
983061ed 267}
268
269/* Writes data from the client buffer to the server side */
b8d8561b 270static void
b177367b 271sslWriteServer(int fd, void *data)
983061ed 272{
b177367b 273 SslStateData *sslState = data;
983061ed 274 int len;
adb78bd4 275 assert(fd == sslState->server.fd);
276 debug(26, 3) ("sslWriteServer: FD %d, %d bytes to write\n",
277 fd, sslState->client.len);
83704487 278 statCounter.syscalls.sock.writes++;
adb78bd4 279 len = write(fd,
280 sslState->client.buf,
281 sslState->client.len);
282 debug(26, 3) ("sslWriteServer: FD %d, %d bytes written\n", fd, len);
ee1679df 283 if (len > 0) {
adb78bd4 284 fd_bytes(fd, len, FD_WRITE);
83704487 285 kb_incr(&statCounter.server.all.kbytes_out, len);
286 kb_incr(&statCounter.server.other.kbytes_out, len);
adb78bd4 287 assert(len <= sslState->client.len);
288 sslState->client.len -= len;
289 if (sslState->client.len > 0) {
290 /* we didn't write the whole thing */
291 xmemmove(sslState->client.buf,
292 sslState->client.buf + len,
293 sslState->client.len);
0a0bf5db 294 }
983061ed 295 }
adb78bd4 296 cbdataLock(sslState);
297 if (len < 0) {
9bc73deb 298 debug(50, ignoreErrno(errno) ? 3 : 1)
299 ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror());
adb78bd4 300 if (!ignoreErrno(errno))
301 comm_close(fd);
983061ed 302 }
adb78bd4 303 if (cbdataValid(sslState))
304 sslSetSelect(sslState);
305 cbdataUnlock(sslState);
983061ed 306}
307
308/* Writes data from the server buffer to the client side */
b8d8561b 309static void
b177367b 310sslWriteClient(int fd, void *data)
983061ed 311{
b177367b 312 SslStateData *sslState = data;
983061ed 313 int len;
adb78bd4 314 assert(fd == sslState->client.fd);
315 debug(26, 3) ("sslWriteClient: FD %d, %d bytes to write\n",
316 fd, sslState->server.len);
83704487 317 statCounter.syscalls.sock.writes++;
adb78bd4 318 len = write(fd,
319 sslState->server.buf,
320 sslState->server.len);
321 debug(26, 3) ("sslWriteClient: FD %d, %d bytes written\n", fd, len);
ee1679df 322 if (len > 0) {
adb78bd4 323 fd_bytes(fd, len, FD_WRITE);
83704487 324 kb_incr(&statCounter.client_http.kbytes_out, len);
adb78bd4 325 assert(len <= sslState->server.len);
326 sslState->server.len -= len;
327 /* increment total object size */
328 if (sslState->size_ptr)
329 *sslState->size_ptr += len;
330 if (sslState->server.len > 0) {
331 /* we didn't write the whole thing */
332 xmemmove(sslState->server.buf,
333 sslState->server.buf + len,
334 sslState->server.len);
0a0bf5db 335 }
983061ed 336 }
adb78bd4 337 cbdataLock(sslState);
338 if (len < 0) {
9bc73deb 339 debug(50, ignoreErrno(errno) ? 3 : 1)
340 ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror());
adb78bd4 341 if (!ignoreErrno(errno))
342 comm_close(fd);
983061ed 343 }
adb78bd4 344 if (cbdataValid(sslState))
345 sslSetSelect(sslState);
346 cbdataUnlock(sslState);
983061ed 347}
348
b8d8561b 349static void
5c5783a2 350sslTimeout(int fd, void *data)
983061ed 351{
b177367b 352 SslStateData *sslState = data;
a3d5953d 353 debug(26, 3) ("sslTimeout: FD %d\n", fd);
adb78bd4 354 if (sslState->client.fd > -1)
355 comm_close(sslState->client.fd);
356 if (sslState->server.fd > -1)
357 comm_close(sslState->server.fd);
983061ed 358}
359
b8d8561b 360static void
b177367b 361sslConnected(int fd, void *data)
983061ed 362{
b177367b 363 SslStateData *sslState = data;
a3d5953d 364 debug(26, 3) ("sslConnected: FD %d sslState=%p\n", fd, sslState);
974ba0ee 365 *sslState->status_ptr = HTTP_OK;
54cff85f 366 xstrncpy(sslState->server.buf, conn_established, SQUID_TCP_SO_RCVBUF);
983061ed 367 sslState->server.len = strlen(conn_established);
adb78bd4 368 sslSetSelect(sslState);
983061ed 369}
370
b8d8561b 371static void
adb78bd4 372sslErrorComplete(int fdnotused, void *data, size_t sizenotused)
30a4f2a8 373{
adb78bd4 374 SslStateData *sslState = data;
9b312a19 375 assert(sslState != NULL);
adb78bd4 376 if (sslState->client.fd > -1)
377 comm_close(sslState->client.fd);
378 if (sslState->server.fd > -1)
379 comm_close(sslState->server.fd);
30a4f2a8 380}
381
983061ed 382
b8d8561b 383static void
79d39a72 384sslConnectDone(int fdnotused, int status, void *data)
983061ed 385{
b15fe823 386 SslStateData *sslState = data;
30a4f2a8 387 request_t *request = sslState->request;
9b312a19 388 ErrorState *err = NULL;
890b0fa8 389 if (sslState->servers->peer)
390 hierarchyNote(&sslState->request->hier, sslState->servers->code,
391 sslState->servers->peer->host);
392 else if (Config.onoff.log_ip_on_direct)
393 hierarchyNote(&sslState->request->hier, sslState->servers->code,
a4b8110e 394 fd_table[sslState->server.fd].ipaddr);
890b0fa8 395 else
396 hierarchyNote(&sslState->request->hier, sslState->servers->code,
a4b8110e 397 sslState->host);
edeb28fd 398 if (status == COMM_ERR_DNS) {
a3d5953d 399 debug(26, 4) ("sslConnect: Unknown host: %s\n", sslState->host);
fe40a877 400 err = errorCon(ERR_DNS_FAIL, HTTP_NOT_FOUND);
974ba0ee 401 *sslState->status_ptr = HTTP_NOT_FOUND;
9b312a19 402 err->request = requestLink(request);
403 err->dnsserver_msg = xstrdup(dns_error_message);
404 err->callback = sslErrorComplete;
405 err->callback_data = sslState;
406 errorSend(sslState->client.fd, err);
edeb28fd 407 } else if (status != COMM_OK) {
fe40a877 408 err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
974ba0ee 409 *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
c45ed9ad 410 err->xerrno = errno;
9b312a19 411 err->host = xstrdup(sslState->host);
412 err->port = sslState->port;
413 err->request = requestLink(request);
414 err->callback = sslErrorComplete;
415 err->callback_data = sslState;
416 errorSend(sslState->client.fd, err);
fe40a877 417 } else {
64d8034e 418 if (sslState->servers->peer)
fe40a877 419 sslProxyConnected(sslState->server.fd, sslState);
4e3f29eb 420 else
fe40a877 421 sslConnected(sslState->server.fd, sslState);
1afe05c5 422 commSetTimeout(sslState->server.fd,
423 Config.Timeout.read,
424 sslTimeout,
425 sslState);
447e176b 426#if DELAY_POOLS
59715b38 427 commSetDefer(sslState->server.fd, sslDeferServerRead, sslState);
447e176b 428#endif
983061ed 429 }
983061ed 430}
30a4f2a8 431
28c60158 432CBDATA_TYPE(SslStateData);
770f051d 433void
974ba0ee 434sslStart(int fd, const char *url, request_t * request, size_t * size_ptr, int *status_ptr)
30a4f2a8 435{
436 /* Create state structure. */
437 SslStateData *sslState = NULL;
438 int sock;
9b312a19 439 ErrorState *err = NULL;
f1003989 440 aclCheck_t ch;
441 int answer;
442 /*
a4b8110e 443 * client_addr == no_addr indicates this is an "internal" request
444 * from peer_digest.c, asn.c, netdb.c, etc and should always
445 * be allowed. yuck, I know.
446 */
f1003989 447 if (request->client_addr.s_addr != no_addr.s_addr) {
448 /*
a4b8110e 449 * Check if this host is allowed to fetch MISSES from us (miss_access)
450 */
f1003989 451 memset(&ch, '\0', sizeof(aclCheck_t));
452 ch.src_addr = request->client_addr;
453 ch.my_addr = request->my_addr;
454 ch.my_port = request->my_port;
455 ch.request = request;
456 answer = aclCheckFast(Config.accessList.miss, &ch);
457 if (answer == 0) {
458 err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN);
974ba0ee 459 *sslState->status_ptr = HTTP_FORBIDDEN;
f1003989 460 err->request = requestLink(request);
461 err->src_addr = request->client_addr;
462 errorSend(fd, err);
463 return;
464 }
465 }
a3d5953d 466 debug(26, 3) ("sslStart: '%s %s'\n",
30a4f2a8 467 RequestMethodStr[request->method], url);
83704487 468 statCounter.server.all.requests++;
469 statCounter.server.other.requests++;
30a4f2a8 470 /* Create socket. */
16b204c4 471 sock = comm_open(SOCK_STREAM,
472 0,
473 Config.Addrs.tcp_outgoing,
474 0,
475 COMM_NONBLOCKING,
476 url);
30a4f2a8 477 if (sock == COMM_ERROR) {
a3d5953d 478 debug(26, 4) ("sslStart: Failed because we're out of sockets.\n");
fe40a877 479 err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
974ba0ee 480 *sslState->status_ptr = HTTP_INTERNAL_SERVER_ERROR;
c45ed9ad 481 err->xerrno = errno;
9b312a19 482 err->request = requestLink(request);
483 errorSend(fd, err);
770f051d 484 return;
30a4f2a8 485 }
28c60158 486 CBDATA_INIT_TYPE(SslStateData);
487 sslState = CBDATA_ALLOC(SslStateData, NULL);
59715b38 488#if DELAY_POOLS
489 sslState->delay_id = delayClient(request);
b6a2f15e 490 delayRegisterDelayIdPtr(&sslState->delay_id);
59715b38 491#endif
30a4f2a8 492 sslState->url = xstrdup(url);
493 sslState->request = requestLink(request);
30a4f2a8 494 sslState->size_ptr = size_ptr;
974ba0ee 495 sslState->status_ptr = status_ptr;
30a4f2a8 496 sslState->client.fd = fd;
497 sslState->server.fd = sock;
498 sslState->server.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
499 sslState->client.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
500 comm_add_close_handler(sslState->server.fd,
adb78bd4 501 sslServerClosed,
cd1fb0eb 502 sslState);
30a4f2a8 503 comm_add_close_handler(sslState->client.fd,
b177367b 504 sslClientClosed,
cd1fb0eb 505 sslState);
5c5783a2 506 commSetTimeout(sslState->client.fd,
4f92c80c 507 Config.Timeout.lifetime,
508 sslTimeout,
509 sslState);
cf1edeae 510 commSetTimeout(sslState->server.fd,
511 Config.Timeout.connect,
512 sslTimeout,
513 sslState);
b6c0e933 514 peerSelect(request,
641941c0 515 NULL,
b6c0e933 516 sslPeerSelectComplete,
b6c0e933 517 sslState);
adb78bd4 518 /*
519 * Disable the client read handler until peer selection is complete
520 * Take control away from client_side.c.
521 */
522 commSetSelect(sslState->client.fd, COMM_SELECT_READ, NULL, NULL, 0);
30a4f2a8 523}
98ffb7e4 524
b8d8561b 525static void
b177367b 526sslProxyConnected(int fd, void *data)
98ffb7e4 527{
b177367b 528 SslStateData *sslState = data;
e1e72f06 529 MemBuf mb;
530 HttpHeader hdr_out;
531 Packer p;
b4b5fd95 532 http_state_flags flags;
a3d5953d 533 debug(26, 3) ("sslProxyConnected: FD %d sslState=%p\n", fd, sslState);
b4b5fd95 534 memset(&flags, '\0', sizeof(flags));
e1e72f06 535 memBufDefInit(&mb);
536 memBufPrintf(&mb, "CONNECT %s HTTP/1.0\r\n", sslState->url);
537 httpBuildRequestHeader(sslState->request,
538 sslState->request,
5999b776 539 NULL, /* StoreEntry */
e1e72f06 540 &hdr_out,
541 sslState->client.fd,
b4b5fd95 542 flags); /* flags */
e1e72f06 543 packerToMemInit(&p, &mb);
544 httpHeaderPackInto(&hdr_out, &p);
545 httpHeaderClean(&hdr_out);
546 packerClean(&p);
547 memBufAppend(&mb, "\r\n", 2);
548 xstrncpy(sslState->client.buf, mb.buf, SQUID_TCP_SO_RCVBUF);
549 debug(26, 3) ("sslProxyConnected: Sending {%s}\n", sslState->client.buf);
550 sslState->client.len = mb.size;
e1e72f06 551 memBufClean(&mb);
86cf9987 552 commSetTimeout(sslState->server.fd,
553 Config.Timeout.read,
554 sslTimeout,
555 sslState);
adb78bd4 556 sslSetSelect(sslState);
98ffb7e4 557}
33ea9fff 558
33ea9fff 559static void
db1cd23c 560sslPeerSelectComplete(FwdServer * fs, void *data)
33ea9fff 561{
562 SslStateData *sslState = data;
563 request_t *request = sslState->request;
deb79f06 564 peer *g = NULL;
db1cd23c 565 if (fs == NULL) {
566 ErrorState *err;
567 err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
974ba0ee 568 *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
db1cd23c 569 err->request = requestLink(sslState->request);
570 err->callback = sslErrorComplete;
571 err->callback_data = sslState;
572 errorSend(sslState->client.fd, err);
573 return;
574 }
64d8034e 575 sslState->servers = fs;
db1cd23c 576 sslState->host = fs->peer ? fs->peer->host : request->host;
577 if (fs->peer == NULL) {
b3b64e58 578 sslState->port = request->port;
db1cd23c 579 } else if (fs->peer->http_port != 0) {
580 sslState->port = fs->peer->http_port;
581 } else if ((g = peerFindByName(fs->peer->host))) {
b3b64e58 582 sslState->port = g->http_port;
33ea9fff 583 } else {
b3b64e58 584 sslState->port = CACHE_HTTP_PORT;
33ea9fff 585 }
1f38f50a 586 if (fs->peer) {
587 sslState->request->peer_login = fs->peer->login;
588 sslState->request->flags.proxying = 1;
589 } else {
94439e4e 590 sslState->request->peer_login = NULL;
1f38f50a 591 sslState->request->flags.proxying = 0;
592 }
59715b38 593#if DELAY_POOLS
594 /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
1ecaa0a0 595 if (g && g->options.no_delay && sslState->delay_id) {
596 delayUnregisterDelayIdPtr(&sslState->delay_id);
59715b38 597 sslState->delay_id = 0;
1ecaa0a0 598 }
59715b38 599#endif
edeb28fd 600 commConnectStart(sslState->server.fd,
601 sslState->host,
602 sslState->port,
603 sslConnectDone,
33ea9fff 604 sslState);
605}