]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl.cc
fix headers to allow inclusion into C++ source
[thirdparty/squid.git] / src / ssl.cc
CommitLineData
95d659f0 1
983061ed 2/*
29b8d8d6 3 * $Id: ssl.cc,v 1.122 2002/09/15 06:40:57 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"
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",
ed19251a 197 fd, (int) read_sz, sslState->server.len);
447e176b 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++;
1f7c9178 203 len = FD_READ_METHOD(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 }
fa80a8ef 214 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
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 }
fa80a8ef 223 if (cbdataReferenceValid(sslState))
adb78bd4 224 sslSetSelect(sslState);
fa80a8ef 225 cbdataInternalUnlock(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++;
1f7c9178 239 len = FD_READ_METHOD(fd,
adb78bd4 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 }
fa80a8ef 248 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
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 }
fa80a8ef 264 if (cbdataReferenceValid(sslState))
adb78bd4 265 sslSetSelect(sslState);
fa80a8ef 266 cbdataInternalUnlock(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++;
1f7c9178 279 len = FD_WRITE_METHOD(fd,
adb78bd4 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 }
fa80a8ef 296 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
adb78bd4 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 }
fa80a8ef 303 if (cbdataReferenceValid(sslState))
adb78bd4 304 sslSetSelect(sslState);
fa80a8ef 305 cbdataInternalUnlock(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++;
1f7c9178 318 len = FD_WRITE_METHOD(fd,
adb78bd4 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 }
fa80a8ef 337 cbdataInternalLock(sslState); /* ??? should be locked by the caller... */
adb78bd4 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 }
fa80a8ef 344 if (cbdataReferenceValid(sslState))
adb78bd4 345 sslSetSelect(sslState);
fa80a8ef 346 cbdataInternalUnlock(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
3d7e9d7c 384sslConnectDone(int fdnotused, comm_err_t status, void *data)
983061ed 385{
b15fe823 386 SslStateData *sslState = data;
30a4f2a8 387 request_t *request = sslState->request;
9b312a19 388 ErrorState *err = NULL;
29b8d8d6 389 if (sslState->servers->_peer)
890b0fa8 390 hierarchyNote(&sslState->request->hier, sslState->servers->code,
29b8d8d6 391 sslState->servers->_peer->host);
890b0fa8 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 {
29b8d8d6 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
d5964d58 434sslStart(clientHttpRequest * http, 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;
d5964d58 442 int fd = http->conn->fd;
443 request_t *request = http->request;
444 char *url = http->uri;
f1003989 445 /*
a4b8110e 446 * client_addr == no_addr indicates this is an "internal" request
447 * from peer_digest.c, asn.c, netdb.c, etc and should always
448 * be allowed. yuck, I know.
449 */
f1003989 450 if (request->client_addr.s_addr != no_addr.s_addr) {
451 /*
a4b8110e 452 * Check if this host is allowed to fetch MISSES from us (miss_access)
453 */
f1003989 454 memset(&ch, '\0', sizeof(aclCheck_t));
455 ch.src_addr = request->client_addr;
456 ch.my_addr = request->my_addr;
457 ch.my_port = request->my_port;
458 ch.request = request;
459 answer = aclCheckFast(Config.accessList.miss, &ch);
460 if (answer == 0) {
461 err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN);
3b3ce25a 462 *status_ptr = HTTP_FORBIDDEN;
f1003989 463 err->request = requestLink(request);
464 err->src_addr = request->client_addr;
465 errorSend(fd, err);
466 return;
467 }
468 }
a3d5953d 469 debug(26, 3) ("sslStart: '%s %s'\n",
30a4f2a8 470 RequestMethodStr[request->method], url);
83704487 471 statCounter.server.all.requests++;
472 statCounter.server.other.requests++;
30a4f2a8 473 /* Create socket. */
d6827718 474 sock = comm_openex(SOCK_STREAM,
16b204c4 475 0,
d6827718 476 getOutgoingAddr(request),
16b204c4 477 0,
478 COMM_NONBLOCKING,
d6827718 479 getOutgoingTOS(request),
16b204c4 480 url);
30a4f2a8 481 if (sock == COMM_ERROR) {
a3d5953d 482 debug(26, 4) ("sslStart: Failed because we're out of sockets.\n");
fe40a877 483 err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
3b3ce25a 484 *status_ptr = HTTP_INTERNAL_SERVER_ERROR;
c45ed9ad 485 err->xerrno = errno;
9b312a19 486 err->request = requestLink(request);
487 errorSend(fd, err);
770f051d 488 return;
30a4f2a8 489 }
28c60158 490 CBDATA_INIT_TYPE(SslStateData);
72711e31 491 sslState = cbdataAlloc(SslStateData);
59715b38 492#if DELAY_POOLS
d5964d58 493 sslState->delay_id = delayClient(http);
b6a2f15e 494 delayRegisterDelayIdPtr(&sslState->delay_id);
59715b38 495#endif
30a4f2a8 496 sslState->url = xstrdup(url);
497 sslState->request = requestLink(request);
30a4f2a8 498 sslState->size_ptr = size_ptr;
974ba0ee 499 sslState->status_ptr = status_ptr;
30a4f2a8 500 sslState->client.fd = fd;
501 sslState->server.fd = sock;
502 sslState->server.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
503 sslState->client.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
504 comm_add_close_handler(sslState->server.fd,
adb78bd4 505 sslServerClosed,
cd1fb0eb 506 sslState);
30a4f2a8 507 comm_add_close_handler(sslState->client.fd,
b177367b 508 sslClientClosed,
cd1fb0eb 509 sslState);
5c5783a2 510 commSetTimeout(sslState->client.fd,
4f92c80c 511 Config.Timeout.lifetime,
512 sslTimeout,
513 sslState);
cf1edeae 514 commSetTimeout(sslState->server.fd,
515 Config.Timeout.connect,
516 sslTimeout,
517 sslState);
b6c0e933 518 peerSelect(request,
641941c0 519 NULL,
b6c0e933 520 sslPeerSelectComplete,
b6c0e933 521 sslState);
adb78bd4 522 /*
523 * Disable the client read handler until peer selection is complete
524 * Take control away from client_side.c.
525 */
526 commSetSelect(sslState->client.fd, COMM_SELECT_READ, NULL, NULL, 0);
30a4f2a8 527}
98ffb7e4 528
b8d8561b 529static void
b177367b 530sslProxyConnected(int fd, void *data)
98ffb7e4 531{
b177367b 532 SslStateData *sslState = data;
e1e72f06 533 MemBuf mb;
534 HttpHeader hdr_out;
535 Packer p;
b4b5fd95 536 http_state_flags flags;
a3d5953d 537 debug(26, 3) ("sslProxyConnected: FD %d sslState=%p\n", fd, sslState);
b4b5fd95 538 memset(&flags, '\0', sizeof(flags));
2f2b4d20 539 flags.proxying = sslState->request->flags.proxying;
e1e72f06 540 memBufDefInit(&mb);
541 memBufPrintf(&mb, "CONNECT %s HTTP/1.0\r\n", sslState->url);
542 httpBuildRequestHeader(sslState->request,
543 sslState->request,
5999b776 544 NULL, /* StoreEntry */
e1e72f06 545 &hdr_out,
546 sslState->client.fd,
b4b5fd95 547 flags); /* flags */
e1e72f06 548 packerToMemInit(&p, &mb);
549 httpHeaderPackInto(&hdr_out, &p);
550 httpHeaderClean(&hdr_out);
551 packerClean(&p);
552 memBufAppend(&mb, "\r\n", 2);
553 xstrncpy(sslState->client.buf, mb.buf, SQUID_TCP_SO_RCVBUF);
554 debug(26, 3) ("sslProxyConnected: Sending {%s}\n", sslState->client.buf);
555 sslState->client.len = mb.size;
e1e72f06 556 memBufClean(&mb);
86cf9987 557 commSetTimeout(sslState->server.fd,
558 Config.Timeout.read,
559 sslTimeout,
560 sslState);
adb78bd4 561 sslSetSelect(sslState);
98ffb7e4 562}
33ea9fff 563
33ea9fff 564static void
db1cd23c 565sslPeerSelectComplete(FwdServer * fs, void *data)
33ea9fff 566{
567 SslStateData *sslState = data;
568 request_t *request = sslState->request;
deb79f06 569 peer *g = NULL;
db1cd23c 570 if (fs == NULL) {
571 ErrorState *err;
572 err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
974ba0ee 573 *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
db1cd23c 574 err->request = requestLink(sslState->request);
575 err->callback = sslErrorComplete;
576 err->callback_data = sslState;
577 errorSend(sslState->client.fd, err);
578 return;
579 }
64d8034e 580 sslState->servers = fs;
29b8d8d6 581 sslState->host = fs->_peer ? fs->_peer->host : request->host;
582 if (fs->_peer == NULL) {
b3b64e58 583 sslState->port = request->port;
29b8d8d6 584 } else if (fs->_peer->http_port != 0) {
585 sslState->port = fs->_peer->http_port;
586 } else if ((g = peerFindByName(fs->_peer->host))) {
b3b64e58 587 sslState->port = g->http_port;
33ea9fff 588 } else {
b3b64e58 589 sslState->port = CACHE_HTTP_PORT;
33ea9fff 590 }
29b8d8d6 591 if (fs->_peer) {
592 sslState->request->peer_login = fs->_peer->login;
1f38f50a 593 sslState->request->flags.proxying = 1;
594 } else {
94439e4e 595 sslState->request->peer_login = NULL;
1f38f50a 596 sslState->request->flags.proxying = 0;
597 }
59715b38 598#if DELAY_POOLS
599 /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
1ecaa0a0 600 if (g && g->options.no_delay && sslState->delay_id) {
601 delayUnregisterDelayIdPtr(&sslState->delay_id);
59715b38 602 sslState->delay_id = 0;
1ecaa0a0 603 }
59715b38 604#endif
edeb28fd 605 commConnectStart(sslState->server.fd,
606 sslState->host,
607 sslState->port,
608 sslConnectDone,
33ea9fff 609 sslState);
610}