]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl.cc
Summary: Merge from delay-class-4
[thirdparty/squid.git] / src / ssl.cc
CommitLineData
95d659f0 1
983061ed 2/*
b67e2c8c 3 * $Id: ssl.cc,v 1.134 2003/02/05 10:36:54 robertc 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"
528b2c61 37#include "HttpRequest.h"
38#include "fde.h"
9f518b4a 39#include "comm.h"
528b2c61 40#include "client_side_request.h"
4fb35c3c 41#include "ACLChecklist.h"
b67e2c8c 42#if DELAY_POOLS
43#include "DelayId.h"
44#endif
983061ed 45
46typedef struct {
47 char *url;
98ffb7e4 48 char *host; /* either request->host or proxy host */
49 u_short port;
983061ed 50 request_t *request;
64d8034e 51 FwdServer *servers;
983061ed 52 struct {
53 int fd;
54 int len;
983061ed 55 char *buf;
56 } client, server;
88738790 57 size_t *size_ptr; /* pointer to size in an ConnStateData for logging */
974ba0ee 58 int *status_ptr; /* pointer to status for logging */
59715b38 59#if DELAY_POOLS
b67e2c8c 60 DelayId delayId;
59715b38 61#endif
983061ed 62} SslStateData;
63
0ee4272b 64static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n";
983061ed 65
54cff85f 66static CNCB sslConnectDone;
67static ERCB sslErrorComplete;
adb78bd4 68static PF sslServerClosed;
54cff85f 69static PF sslClientClosed;
c4b7a5a9 70static IOCB sslReadClient;
71static IOCB sslReadServer;
5c5783a2 72static PF sslTimeout;
9f518b4a 73static IOWCB sslWriteClientDone;
74static IOWCB sslWriteServerDone;
54cff85f 75static PSC sslPeerSelectComplete;
adb78bd4 76static void sslStateFree(SslStateData * sslState);
f5b8bbc4 77static void sslConnected(int fd, void *);
78static void sslProxyConnected(int fd, void *);
447e176b 79#if DELAY_POOLS
80static DEFER sslDeferServerRead;
81#endif
30a4f2a8 82
b8d8561b 83static void
adb78bd4 84sslServerClosed(int fd, void *data)
30a4f2a8 85{
e6ccf245 86 SslStateData *sslState = (SslStateData *)data;
adb78bd4 87 debug(26, 3) ("sslServerClosed: FD %d\n", fd);
88 assert(fd == sslState->server.fd);
89 sslState->server.fd = -1;
90 if (sslState->client.fd == -1)
91 sslStateFree(sslState);
30a4f2a8 92}
93
b177367b 94static void
95sslClientClosed(int fd, void *data)
30a4f2a8 96{
e6ccf245 97 SslStateData *sslState = (SslStateData *)data;
a3d5953d 98 debug(26, 3) ("sslClientClosed: FD %d\n", fd);
adb78bd4 99 assert(fd == sslState->client.fd);
100 sslState->client.fd = -1;
101 if (sslState->server.fd == -1)
102 sslStateFree(sslState);
30a4f2a8 103}
983061ed 104
b177367b 105static void
adb78bd4 106sslStateFree(SslStateData * sslState)
983061ed 107{
adb78bd4 108 debug(26, 3) ("sslStateFree: sslState=%p\n", sslState);
109 assert(sslState != NULL);
110 assert(sslState->client.fd == -1);
111 assert(sslState->server.fd == -1);
983061ed 112 safe_free(sslState->server.buf);
113 safe_free(sslState->client.buf);
adb78bd4 114 safe_free(sslState->url);
64d8034e 115 fwdServersFree(&sslState->servers);
adb78bd4 116 sslState->host = NULL;
30a4f2a8 117 requestUnlink(sslState->request);
7dd44885 118 sslState->request = NULL;
119 cbdataFree(sslState);
983061ed 120}
121
447e176b 122#if DELAY_POOLS
123static int
124sslDeferServerRead(int fdnotused, void *data)
125{
e6ccf245 126 SslStateData *s = (SslStateData *)data;
b67e2c8c 127 int i = s->delayId.bytesWanted(0, INT_MAX);
7e3ce7b9 128 if (i == INT_MAX)
129 return 0;
130 if (i == 0)
131 return 1;
132 return -1;
447e176b 133}
134#endif
135
adb78bd4 136
983061ed 137/* Read from server side and queue it for writing to the client */
b8d8561b 138static void
c4b7a5a9 139sslReadServer(int fd, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data)
983061ed 140{
e6ccf245 141 SslStateData *sslState = (SslStateData *)data;
c4b7a5a9 142
adb78bd4 143 assert(fd == sslState->server.fd);
447e176b 144 errno = 0;
145#if DELAY_POOLS
b67e2c8c 146 len = sslState->delayId.bytesWanted(1, len);
447e176b 147#endif
c4b7a5a9 148 /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */
149 if (errcode == COMM_ERR_CLOSING) {
150 return;
151 }
152 debug(26, 3) ("sslReadServer: FD %d, read %d bytes\n", fd, (int)len);
ee1679df 153 if (len > 0) {
447e176b 154#if DELAY_POOLS
b67e2c8c 155 sslState->delayId.bytesIn(len);
447e176b 156#endif
83704487 157 kb_incr(&statCounter.server.all.kbytes_in, len);
158 kb_incr(&statCounter.server.other.kbytes_in, len);
adb78bd4 159 sslState->server.len += len;
ee1679df 160 }
fa80a8ef 161 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
983061ed 162 if (len < 0) {
9bc73deb 163 debug(50, ignoreErrno(errno) ? 3 : 1)
164 ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror());
adb78bd4 165 if (!ignoreErrno(errno))
166 comm_close(fd);
983061ed 167 } else if (len == 0) {
adb78bd4 168 comm_close(sslState->server.fd);
c4b7a5a9 169 /* Only close the remote end if we've finished queueing data to it */
170 if (sslState->server.len == 0 && sslState->client.fd != -1) {
171 comm_close(sslState->client.fd);
172 }
173 } else if (cbdataReferenceValid(sslState))
9f518b4a 174 comm_write(sslState->client.fd, sslState->server.buf, len, sslWriteClientDone, sslState);
fa80a8ef 175 cbdataInternalUnlock(sslState); /* ??? */
983061ed 176}
177
178/* Read from client side and queue it for writing to the server */
b8d8561b 179static void
c4b7a5a9 180sslReadClient(int fd, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data)
983061ed 181{
e6ccf245 182 SslStateData *sslState = (SslStateData *)data;
adb78bd4 183 assert(fd == sslState->client.fd);
c4b7a5a9 184
185 /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */
186 if (errcode == COMM_ERR_CLOSING) {
187 return;
188 }
189
190 debug(26, 3) ("sslReadClient: FD %d, read %d bytes\n", fd, (int) len);
ee1679df 191 if (len > 0) {
83704487 192 kb_incr(&statCounter.client_http.kbytes_in, len);
adb78bd4 193 sslState->client.len += len;
ee1679df 194 }
fa80a8ef 195 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
983061ed 196 if (len < 0) {
7e0453ea 197 int level = 1;
198#ifdef ECONNRESET
c4b7a5a9 199 if (xerrno == ECONNRESET)
7e0453ea 200 level = 2;
201#endif
c4b7a5a9 202 if (ignoreErrno(xerrno))
7e0453ea 203 level = 3;
c4b7a5a9 204 /* XXX xstrerror() should be changed to take errno as an arg! */
205 errno = xerrno;
7e0453ea 206 debug(50, level) ("sslReadClient: FD %d: read failure: %s\n",
983061ed 207 fd, xstrerror());
c4b7a5a9 208 if (!ignoreErrno(xerrno))
adb78bd4 209 comm_close(fd);
983061ed 210 } else if (len == 0) {
c4b7a5a9 211 comm_close(sslState->client.fd);
212 /* Only close the remote end if we've finished queueing data to it */
213 if (sslState->client.len == 0 && sslState->server.fd != -1) {
214 comm_close(sslState->server.fd);
215 }
216 } else if (cbdataReferenceValid(sslState))
9f518b4a 217 comm_write(sslState->server.fd, sslState->client.buf, len, sslWriteServerDone, sslState);
fa80a8ef 218 cbdataInternalUnlock(sslState); /* ??? */
983061ed 219}
220
221/* Writes data from the client buffer to the server side */
b8d8561b 222static void
9f518b4a 223sslWriteServerDone(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
983061ed 224{
e6ccf245 225 SslStateData *sslState = (SslStateData *)data;
adb78bd4 226 assert(fd == sslState->server.fd);
c4b7a5a9 227 debug(26, 3) ("sslWriteServer: FD %d, %d bytes written\n", fd, (int)len);
228 /* Valid data */
ee1679df 229 if (len > 0) {
83704487 230 kb_incr(&statCounter.server.all.kbytes_out, len);
231 kb_incr(&statCounter.server.other.kbytes_out, len);
c4b7a5a9 232 assert(len == (size_t)sslState->client.len);
233 sslState->client.len = 0;
234 }
235 /* EOF */
236 if (len == 0) {
237 comm_close(sslState->server.fd);
238 return;
239 }
240 /* If the other end has closed, so should we */
241 if (sslState->client.fd == -1) {
242 comm_close(sslState->server.fd);
243 return;
983061ed 244 }
fa80a8ef 245 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
c4b7a5a9 246 /* Error? */
adb78bd4 247 if (len < 0) {
9bc73deb 248 debug(50, ignoreErrno(errno) ? 3 : 1)
249 ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror());
adb78bd4 250 if (!ignoreErrno(errno))
251 comm_close(fd);
983061ed 252 }
c4b7a5a9 253 if (cbdataReferenceValid(sslState)) {
254 assert(sslState->client.len == 0);
255 comm_read(sslState->client.fd, sslState->client.buf, SQUID_TCP_SO_RCVBUF,
256 sslReadClient, sslState);
257 }
fa80a8ef 258 cbdataInternalUnlock(sslState); /* ??? */
983061ed 259}
260
261/* Writes data from the server buffer to the client side */
b8d8561b 262static void
9f518b4a 263sslWriteClientDone(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
983061ed 264{
e6ccf245 265 SslStateData *sslState = (SslStateData *)data;
adb78bd4 266 assert(fd == sslState->client.fd);
c4b7a5a9 267 debug(26, 3) ("sslWriteClient: FD %d, %d bytes written\n", fd, (int)len);
ee1679df 268 if (len > 0) {
83704487 269 kb_incr(&statCounter.client_http.kbytes_out, len);
c4b7a5a9 270 assert(len == (size_t)sslState->server.len);
271 sslState->server.len =0;
adb78bd4 272 /* increment total object size */
273 if (sslState->size_ptr)
274 *sslState->size_ptr += len;
c4b7a5a9 275 }
276 /* EOF */
277 if (len == 0) {
278 comm_close(sslState->client.fd);
279 return;
280 }
281 /* If the other end has closed, so should we */
282 if (sslState->server.fd == -1) {
283 comm_close(sslState->client.fd);
284 return;
983061ed 285 }
fa80a8ef 286 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
c4b7a5a9 287 /* Error? */
adb78bd4 288 if (len < 0) {
9bc73deb 289 debug(50, ignoreErrno(errno) ? 3 : 1)
290 ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror());
adb78bd4 291 if (!ignoreErrno(errno))
292 comm_close(fd);
983061ed 293 }
c4b7a5a9 294 if (cbdataReferenceValid(sslState)) {
295 assert(sslState->server.len == 0);
296 comm_read(sslState->server.fd, sslState->server.buf, SQUID_TCP_SO_RCVBUF,
297 sslReadServer, sslState);
298 }
fa80a8ef 299 cbdataInternalUnlock(sslState); /* ??? */
983061ed 300}
301
b8d8561b 302static void
5c5783a2 303sslTimeout(int fd, void *data)
983061ed 304{
e6ccf245 305 SslStateData *sslState = (SslStateData *)data;
a3d5953d 306 debug(26, 3) ("sslTimeout: FD %d\n", fd);
1e438d1b 307 /* Temporary lock to protect our own feets (comm_close -> sslClientClosed -> Free) */
308 cbdataInternalLock(sslState);
adb78bd4 309 if (sslState->client.fd > -1)
310 comm_close(sslState->client.fd);
311 if (sslState->server.fd > -1)
312 comm_close(sslState->server.fd);
1e438d1b 313 cbdataInternalUnlock(sslState);
983061ed 314}
315
c4b7a5a9 316static void
4dcb4cc5 317sslConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
c4b7a5a9 318{
319 SslStateData *sslState = (SslStateData *)data;
320 if (flag != COMM_OK) {
321 sslErrorComplete(fd, data, 0);
322 return;
323 }
324 if (cbdataReferenceValid(sslState)) {
325 assert(sslState->server.len == 0);
326 comm_read(sslState->server.fd, sslState->server.buf, SQUID_TCP_SO_RCVBUF,
327 sslReadServer, sslState);
328 comm_read(sslState->client.fd, sslState->client.buf, SQUID_TCP_SO_RCVBUF,
329 sslReadClient, sslState);
330 }
331}
332
333
334/*
335 * handle the write completion from a proxy request to an upstream proxy
336 */
337static void
338sslProxyConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, void *data)
339{
340 SslStateData *sslState = (SslStateData *)data;
341 if (flag != COMM_OK) {
342 sslErrorComplete(fd, data, 0);
343 return;
344 }
345 if (cbdataReferenceValid(sslState)) {
346 assert(sslState->server.len == 0);
347 comm_read(sslState->server.fd, sslState->server.buf, SQUID_TCP_SO_RCVBUF,
348 sslReadServer, sslState);
349 comm_read(sslState->client.fd, sslState->client.buf, SQUID_TCP_SO_RCVBUF,
350 sslReadClient, sslState);
351 }
352}
353
b8d8561b 354static void
b177367b 355sslConnected(int fd, void *data)
983061ed 356{
e6ccf245 357 SslStateData *sslState = (SslStateData *)data;
a3d5953d 358 debug(26, 3) ("sslConnected: FD %d sslState=%p\n", fd, sslState);
974ba0ee 359 *sslState->status_ptr = HTTP_OK;
4dcb4cc5 360 comm_write(sslState->client.fd, conn_established, strlen(conn_established),
361 sslConnectedWriteDone, sslState);
983061ed 362}
363
b8d8561b 364static void
adb78bd4 365sslErrorComplete(int fdnotused, void *data, size_t sizenotused)
30a4f2a8 366{
e6ccf245 367 SslStateData *sslState = (SslStateData *)data;
9b312a19 368 assert(sslState != NULL);
adb78bd4 369 if (sslState->client.fd > -1)
370 comm_close(sslState->client.fd);
371 if (sslState->server.fd > -1)
372 comm_close(sslState->server.fd);
30a4f2a8 373}
374
983061ed 375
b8d8561b 376static void
3d7e9d7c 377sslConnectDone(int fdnotused, comm_err_t status, void *data)
983061ed 378{
e6ccf245 379 SslStateData *sslState = (SslStateData *)data;
30a4f2a8 380 request_t *request = sslState->request;
9b312a19 381 ErrorState *err = NULL;
29b8d8d6 382 if (sslState->servers->_peer)
890b0fa8 383 hierarchyNote(&sslState->request->hier, sslState->servers->code,
29b8d8d6 384 sslState->servers->_peer->host);
890b0fa8 385 else if (Config.onoff.log_ip_on_direct)
386 hierarchyNote(&sslState->request->hier, sslState->servers->code,
a4b8110e 387 fd_table[sslState->server.fd].ipaddr);
890b0fa8 388 else
389 hierarchyNote(&sslState->request->hier, sslState->servers->code,
a4b8110e 390 sslState->host);
edeb28fd 391 if (status == COMM_ERR_DNS) {
a3d5953d 392 debug(26, 4) ("sslConnect: Unknown host: %s\n", sslState->host);
fe40a877 393 err = errorCon(ERR_DNS_FAIL, HTTP_NOT_FOUND);
974ba0ee 394 *sslState->status_ptr = HTTP_NOT_FOUND;
9b312a19 395 err->request = requestLink(request);
396 err->dnsserver_msg = xstrdup(dns_error_message);
397 err->callback = sslErrorComplete;
398 err->callback_data = sslState;
399 errorSend(sslState->client.fd, err);
edeb28fd 400 } else if (status != COMM_OK) {
fe40a877 401 err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
974ba0ee 402 *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
c45ed9ad 403 err->xerrno = errno;
9b312a19 404 err->host = xstrdup(sslState->host);
405 err->port = sslState->port;
406 err->request = requestLink(request);
407 err->callback = sslErrorComplete;
408 err->callback_data = sslState;
409 errorSend(sslState->client.fd, err);
fe40a877 410 } else {
29b8d8d6 411 if (sslState->servers->_peer)
fe40a877 412 sslProxyConnected(sslState->server.fd, sslState);
c4b7a5a9 413 else {
fe40a877 414 sslConnected(sslState->server.fd, sslState);
c4b7a5a9 415 }
1afe05c5 416 commSetTimeout(sslState->server.fd,
417 Config.Timeout.read,
418 sslTimeout,
419 sslState);
447e176b 420#if DELAY_POOLS
59715b38 421 commSetDefer(sslState->server.fd, sslDeferServerRead, sslState);
447e176b 422#endif
983061ed 423 }
983061ed 424}
30a4f2a8 425
28c60158 426CBDATA_TYPE(SslStateData);
770f051d 427void
d5964d58 428sslStart(clientHttpRequest * http, size_t * size_ptr, int *status_ptr)
30a4f2a8 429{
430 /* Create state structure. */
431 SslStateData *sslState = NULL;
432 int sock;
9b312a19 433 ErrorState *err = NULL;
f1003989 434 int answer;
d5964d58 435 int fd = http->conn->fd;
436 request_t *request = http->request;
437 char *url = http->uri;
f1003989 438 /*
a4b8110e 439 * client_addr == no_addr indicates this is an "internal" request
440 * from peer_digest.c, asn.c, netdb.c, etc and should always
441 * be allowed. yuck, I know.
442 */
f1003989 443 if (request->client_addr.s_addr != no_addr.s_addr) {
444 /*
a4b8110e 445 * Check if this host is allowed to fetch MISSES from us (miss_access)
446 */
4fb35c3c 447 ACLChecklist ch;
f1003989 448 ch.src_addr = request->client_addr;
449 ch.my_addr = request->my_addr;
450 ch.my_port = request->my_port;
451 ch.request = request;
452 answer = aclCheckFast(Config.accessList.miss, &ch);
453 if (answer == 0) {
454 err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN);
3b3ce25a 455 *status_ptr = HTTP_FORBIDDEN;
f1003989 456 err->request = requestLink(request);
457 err->src_addr = request->client_addr;
458 errorSend(fd, err);
459 return;
460 }
461 }
a3d5953d 462 debug(26, 3) ("sslStart: '%s %s'\n",
30a4f2a8 463 RequestMethodStr[request->method], url);
83704487 464 statCounter.server.all.requests++;
465 statCounter.server.other.requests++;
30a4f2a8 466 /* Create socket. */
d6827718 467 sock = comm_openex(SOCK_STREAM,
16b204c4 468 0,
d6827718 469 getOutgoingAddr(request),
16b204c4 470 0,
471 COMM_NONBLOCKING,
d6827718 472 getOutgoingTOS(request),
16b204c4 473 url);
30a4f2a8 474 if (sock == COMM_ERROR) {
a3d5953d 475 debug(26, 4) ("sslStart: Failed because we're out of sockets.\n");
fe40a877 476 err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
3b3ce25a 477 *status_ptr = HTTP_INTERNAL_SERVER_ERROR;
c45ed9ad 478 err->xerrno = errno;
9b312a19 479 err->request = requestLink(request);
480 errorSend(fd, err);
770f051d 481 return;
30a4f2a8 482 }
28c60158 483 CBDATA_INIT_TYPE(SslStateData);
72711e31 484 sslState = cbdataAlloc(SslStateData);
59715b38 485#if DELAY_POOLS
b67e2c8c 486 sslState->delayId = DelayId::DelayClient(http);
59715b38 487#endif
30a4f2a8 488 sslState->url = xstrdup(url);
489 sslState->request = requestLink(request);
30a4f2a8 490 sslState->size_ptr = size_ptr;
974ba0ee 491 sslState->status_ptr = status_ptr;
30a4f2a8 492 sslState->client.fd = fd;
493 sslState->server.fd = sock;
e6ccf245 494 sslState->server.buf = (char *)xmalloc(SQUID_TCP_SO_RCVBUF);
495 sslState->client.buf = (char *)xmalloc(SQUID_TCP_SO_RCVBUF);
30a4f2a8 496 comm_add_close_handler(sslState->server.fd,
adb78bd4 497 sslServerClosed,
cd1fb0eb 498 sslState);
30a4f2a8 499 comm_add_close_handler(sslState->client.fd,
b177367b 500 sslClientClosed,
cd1fb0eb 501 sslState);
5c5783a2 502 commSetTimeout(sslState->client.fd,
4f92c80c 503 Config.Timeout.lifetime,
504 sslTimeout,
505 sslState);
cf1edeae 506 commSetTimeout(sslState->server.fd,
507 Config.Timeout.connect,
508 sslTimeout,
509 sslState);
b6c0e933 510 peerSelect(request,
641941c0 511 NULL,
b6c0e933 512 sslPeerSelectComplete,
b6c0e933 513 sslState);
adb78bd4 514 /*
515 * Disable the client read handler until peer selection is complete
516 * Take control away from client_side.c.
517 */
518 commSetSelect(sslState->client.fd, COMM_SELECT_READ, NULL, NULL, 0);
30a4f2a8 519}
98ffb7e4 520
b8d8561b 521static void
b177367b 522sslProxyConnected(int fd, void *data)
98ffb7e4 523{
e6ccf245 524 SslStateData *sslState = (SslStateData *)data;
e1e72f06 525 MemBuf mb;
526 HttpHeader hdr_out;
527 Packer p;
b4b5fd95 528 http_state_flags flags;
a3d5953d 529 debug(26, 3) ("sslProxyConnected: FD %d sslState=%p\n", fd, sslState);
b4b5fd95 530 memset(&flags, '\0', sizeof(flags));
2f2b4d20 531 flags.proxying = sslState->request->flags.proxying;
e1e72f06 532 memBufDefInit(&mb);
533 memBufPrintf(&mb, "CONNECT %s HTTP/1.0\r\n", sslState->url);
534 httpBuildRequestHeader(sslState->request,
535 sslState->request,
5999b776 536 NULL, /* StoreEntry */
e1e72f06 537 &hdr_out,
b4b5fd95 538 flags); /* flags */
e1e72f06 539 packerToMemInit(&p, &mb);
540 httpHeaderPackInto(&hdr_out, &p);
541 httpHeaderClean(&hdr_out);
542 packerClean(&p);
543 memBufAppend(&mb, "\r\n", 2);
c4b7a5a9 544
d4cb310b 545 comm_old_write_mbuf(sslState->server.fd, mb, sslProxyConnectedWriteDone, sslState);
c4b7a5a9 546
86cf9987 547 commSetTimeout(sslState->server.fd,
548 Config.Timeout.read,
549 sslTimeout,
550 sslState);
98ffb7e4 551}
33ea9fff 552
33ea9fff 553static void
db1cd23c 554sslPeerSelectComplete(FwdServer * fs, void *data)
33ea9fff 555{
e6ccf245 556 SslStateData *sslState = (SslStateData *)data;
33ea9fff 557 request_t *request = sslState->request;
deb79f06 558 peer *g = NULL;
db1cd23c 559 if (fs == NULL) {
560 ErrorState *err;
561 err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
974ba0ee 562 *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
db1cd23c 563 err->request = requestLink(sslState->request);
564 err->callback = sslErrorComplete;
565 err->callback_data = sslState;
566 errorSend(sslState->client.fd, err);
567 return;
568 }
64d8034e 569 sslState->servers = fs;
29b8d8d6 570 sslState->host = fs->_peer ? fs->_peer->host : request->host;
571 if (fs->_peer == NULL) {
b3b64e58 572 sslState->port = request->port;
29b8d8d6 573 } else if (fs->_peer->http_port != 0) {
574 sslState->port = fs->_peer->http_port;
575 } else if ((g = peerFindByName(fs->_peer->host))) {
b3b64e58 576 sslState->port = g->http_port;
33ea9fff 577 } else {
b3b64e58 578 sslState->port = CACHE_HTTP_PORT;
33ea9fff 579 }
29b8d8d6 580 if (fs->_peer) {
581 sslState->request->peer_login = fs->_peer->login;
1f38f50a 582 sslState->request->flags.proxying = 1;
583 } else {
94439e4e 584 sslState->request->peer_login = NULL;
1f38f50a 585 sslState->request->flags.proxying = 0;
586 }
59715b38 587#if DELAY_POOLS
588 /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
4326a9b6 589 if (g && g->options.no_delay && sslState->delayId) {
b67e2c8c 590 sslState->delayId = DelayId();
1ecaa0a0 591 }
59715b38 592#endif
edeb28fd 593 commConnectStart(sslState->server.fd,
594 sslState->host,
595 sslState->port,
596 sslConnectDone,
33ea9fff 597 sslState);
598}