From: hno <> Date: Sat, 8 Feb 2003 23:16:14 +0000 (+0000) Subject: Renamed ssl.cc to tunnel.cc X-Git-Tag: SQUID_3_0_PRE1~374 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=58a927d98a0eab1d9109a19592d133f19cfdb379;p=thirdparty%2Fsquid.git Renamed ssl.cc to tunnel.cc Next step is to rename functions suitably to denote the two functions provided: a) tunnel mode b) CONNECT forwarding to another proxy, followed by tunnel mode --- diff --git a/src/Makefile.am b/src/Makefile.am index 5941e677ee..08220e4daf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.54 2003/02/05 10:36:48 robertc Exp $ +# $Id: Makefile.am,v 1.55 2003/02/08 16:16:14 hno Exp $ # # Uncomment and customize the following to suit your needs: # @@ -243,7 +243,7 @@ squid_SOURCES = \ send-announce.cc \ $(SNMPSOURCE) \ squid.h \ - ssl.cc \ + tunnel.cc \ $(SSLSOURCE) \ stat.cc \ StatHist.cc \ diff --git a/src/Makefile.in b/src/Makefile.in index 7d703e0b46..b305fd4793 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -16,7 +16,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.279 2003/02/06 10:00:30 robertc Exp $ +# $Id: Makefile.in,v 1.280 2003/02/08 16:16:14 hno Exp $ # # Uncomment and customize the following to suit your needs: # @@ -335,7 +335,7 @@ squid_SOURCES = \ send-announce.cc \ $(SNMPSOURCE) \ squid.h \ - ssl.cc \ + tunnel.cc \ $(SSLSOURCE) \ stat.cc \ StatHist.cc \ diff --git a/src/ssl.cc b/src/ssl.cc deleted file mode 100644 index af6fa9b45a..0000000000 --- a/src/ssl.cc +++ /dev/null @@ -1,598 +0,0 @@ - -/* - * $Id: ssl.cc,v 1.134 2003/02/05 10:36:54 robertc Exp $ - * - * DEBUG: section 26 Secure Sockets Layer Proxy - * AUTHOR: Duane Wessels - * - * SQUID Web Proxy Cache http://www.squid-cache.org/ - * ---------------------------------------------------------- - * - * Squid is the result of efforts by numerous individuals from - * the Internet community; see the CONTRIBUTORS file for full - * details. Many organizations have provided support for Squid's - * development; see the SPONSORS file for full details. Squid is - * Copyrighted (C) 2001 by the Regents of the University of - * California; see the COPYRIGHT file for full details. Squid - * incorporates software developed and/or copyrighted by other - * sources; see the CREDITS file for full details. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. - * - */ - -#include "squid.h" -#include "HttpRequest.h" -#include "fde.h" -#include "comm.h" -#include "client_side_request.h" -#include "ACLChecklist.h" -#if DELAY_POOLS -#include "DelayId.h" -#endif - -typedef struct { - char *url; - char *host; /* either request->host or proxy host */ - u_short port; - request_t *request; - FwdServer *servers; - struct { - int fd; - int len; - char *buf; - } client, server; - size_t *size_ptr; /* pointer to size in an ConnStateData for logging */ - int *status_ptr; /* pointer to status for logging */ -#if DELAY_POOLS - DelayId delayId; -#endif -} SslStateData; - -static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n"; - -static CNCB sslConnectDone; -static ERCB sslErrorComplete; -static PF sslServerClosed; -static PF sslClientClosed; -static IOCB sslReadClient; -static IOCB sslReadServer; -static PF sslTimeout; -static IOWCB sslWriteClientDone; -static IOWCB sslWriteServerDone; -static PSC sslPeerSelectComplete; -static void sslStateFree(SslStateData * sslState); -static void sslConnected(int fd, void *); -static void sslProxyConnected(int fd, void *); -#if DELAY_POOLS -static DEFER sslDeferServerRead; -#endif - -static void -sslServerClosed(int fd, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - debug(26, 3) ("sslServerClosed: FD %d\n", fd); - assert(fd == sslState->server.fd); - sslState->server.fd = -1; - if (sslState->client.fd == -1) - sslStateFree(sslState); -} - -static void -sslClientClosed(int fd, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - debug(26, 3) ("sslClientClosed: FD %d\n", fd); - assert(fd == sslState->client.fd); - sslState->client.fd = -1; - if (sslState->server.fd == -1) - sslStateFree(sslState); -} - -static void -sslStateFree(SslStateData * sslState) -{ - debug(26, 3) ("sslStateFree: sslState=%p\n", sslState); - assert(sslState != NULL); - assert(sslState->client.fd == -1); - assert(sslState->server.fd == -1); - safe_free(sslState->server.buf); - safe_free(sslState->client.buf); - safe_free(sslState->url); - fwdServersFree(&sslState->servers); - sslState->host = NULL; - requestUnlink(sslState->request); - sslState->request = NULL; - cbdataFree(sslState); -} - -#if DELAY_POOLS -static int -sslDeferServerRead(int fdnotused, void *data) -{ - SslStateData *s = (SslStateData *)data; - int i = s->delayId.bytesWanted(0, INT_MAX); - if (i == INT_MAX) - return 0; - if (i == 0) - return 1; - return -1; -} -#endif - - -/* Read from server side and queue it for writing to the client */ -static void -sslReadServer(int fd, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - - assert(fd == sslState->server.fd); - errno = 0; -#if DELAY_POOLS - len = sslState->delayId.bytesWanted(1, len); -#endif - /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */ - if (errcode == COMM_ERR_CLOSING) { - return; - } - debug(26, 3) ("sslReadServer: FD %d, read %d bytes\n", fd, (int)len); - if (len > 0) { -#if DELAY_POOLS - sslState->delayId.bytesIn(len); -#endif - kb_incr(&statCounter.server.all.kbytes_in, len); - kb_incr(&statCounter.server.other.kbytes_in, len); - sslState->server.len += len; - } - cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ - if (len < 0) { - debug(50, ignoreErrno(errno) ? 3 : 1) - ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror()); - if (!ignoreErrno(errno)) - comm_close(fd); - } else if (len == 0) { - comm_close(sslState->server.fd); - /* Only close the remote end if we've finished queueing data to it */ - if (sslState->server.len == 0 && sslState->client.fd != -1) { - comm_close(sslState->client.fd); - } - } else if (cbdataReferenceValid(sslState)) - comm_write(sslState->client.fd, sslState->server.buf, len, sslWriteClientDone, sslState); - cbdataInternalUnlock(sslState); /* ??? */ -} - -/* Read from client side and queue it for writing to the server */ -static void -sslReadClient(int fd, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - assert(fd == sslState->client.fd); - - /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */ - if (errcode == COMM_ERR_CLOSING) { - return; - } - - debug(26, 3) ("sslReadClient: FD %d, read %d bytes\n", fd, (int) len); - if (len > 0) { - kb_incr(&statCounter.client_http.kbytes_in, len); - sslState->client.len += len; - } - cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ - if (len < 0) { - int level = 1; -#ifdef ECONNRESET - if (xerrno == ECONNRESET) - level = 2; -#endif - if (ignoreErrno(xerrno)) - level = 3; - /* XXX xstrerror() should be changed to take errno as an arg! */ - errno = xerrno; - debug(50, level) ("sslReadClient: FD %d: read failure: %s\n", - fd, xstrerror()); - if (!ignoreErrno(xerrno)) - comm_close(fd); - } else if (len == 0) { - comm_close(sslState->client.fd); - /* Only close the remote end if we've finished queueing data to it */ - if (sslState->client.len == 0 && sslState->server.fd != -1) { - comm_close(sslState->server.fd); - } - } else if (cbdataReferenceValid(sslState)) - comm_write(sslState->server.fd, sslState->client.buf, len, sslWriteServerDone, sslState); - cbdataInternalUnlock(sslState); /* ??? */ -} - -/* Writes data from the client buffer to the server side */ -static void -sslWriteServerDone(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - assert(fd == sslState->server.fd); - debug(26, 3) ("sslWriteServer: FD %d, %d bytes written\n", fd, (int)len); - /* Valid data */ - if (len > 0) { - kb_incr(&statCounter.server.all.kbytes_out, len); - kb_incr(&statCounter.server.other.kbytes_out, len); - assert(len == (size_t)sslState->client.len); - sslState->client.len = 0; - } - /* EOF */ - if (len == 0) { - comm_close(sslState->server.fd); - return; - } - /* If the other end has closed, so should we */ - if (sslState->client.fd == -1) { - comm_close(sslState->server.fd); - return; - } - cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ - /* Error? */ - if (len < 0) { - debug(50, ignoreErrno(errno) ? 3 : 1) - ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror()); - if (!ignoreErrno(errno)) - comm_close(fd); - } - if (cbdataReferenceValid(sslState)) { - assert(sslState->client.len == 0); - comm_read(sslState->client.fd, sslState->client.buf, SQUID_TCP_SO_RCVBUF, - sslReadClient, sslState); - } - cbdataInternalUnlock(sslState); /* ??? */ -} - -/* Writes data from the server buffer to the client side */ -static void -sslWriteClientDone(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - assert(fd == sslState->client.fd); - debug(26, 3) ("sslWriteClient: FD %d, %d bytes written\n", fd, (int)len); - if (len > 0) { - kb_incr(&statCounter.client_http.kbytes_out, len); - assert(len == (size_t)sslState->server.len); - sslState->server.len =0; - /* increment total object size */ - if (sslState->size_ptr) - *sslState->size_ptr += len; - } - /* EOF */ - if (len == 0) { - comm_close(sslState->client.fd); - return; - } - /* If the other end has closed, so should we */ - if (sslState->server.fd == -1) { - comm_close(sslState->client.fd); - return; - } - cbdataInternalLock(sslState); /* ??? should be locked by the caller... */ - /* Error? */ - if (len < 0) { - debug(50, ignoreErrno(errno) ? 3 : 1) - ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror()); - if (!ignoreErrno(errno)) - comm_close(fd); - } - if (cbdataReferenceValid(sslState)) { - assert(sslState->server.len == 0); - comm_read(sslState->server.fd, sslState->server.buf, SQUID_TCP_SO_RCVBUF, - sslReadServer, sslState); - } - cbdataInternalUnlock(sslState); /* ??? */ -} - -static void -sslTimeout(int fd, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - debug(26, 3) ("sslTimeout: FD %d\n", fd); - /* Temporary lock to protect our own feets (comm_close -> sslClientClosed -> Free) */ - cbdataInternalLock(sslState); - if (sslState->client.fd > -1) - comm_close(sslState->client.fd); - if (sslState->server.fd > -1) - comm_close(sslState->server.fd); - cbdataInternalUnlock(sslState); -} - -static void -sslConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - if (flag != COMM_OK) { - sslErrorComplete(fd, data, 0); - return; - } - if (cbdataReferenceValid(sslState)) { - assert(sslState->server.len == 0); - comm_read(sslState->server.fd, sslState->server.buf, SQUID_TCP_SO_RCVBUF, - sslReadServer, sslState); - comm_read(sslState->client.fd, sslState->client.buf, SQUID_TCP_SO_RCVBUF, - sslReadClient, sslState); - } -} - - -/* - * handle the write completion from a proxy request to an upstream proxy - */ -static void -sslProxyConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - if (flag != COMM_OK) { - sslErrorComplete(fd, data, 0); - return; - } - if (cbdataReferenceValid(sslState)) { - assert(sslState->server.len == 0); - comm_read(sslState->server.fd, sslState->server.buf, SQUID_TCP_SO_RCVBUF, - sslReadServer, sslState); - comm_read(sslState->client.fd, sslState->client.buf, SQUID_TCP_SO_RCVBUF, - sslReadClient, sslState); - } -} - -static void -sslConnected(int fd, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - debug(26, 3) ("sslConnected: FD %d sslState=%p\n", fd, sslState); - *sslState->status_ptr = HTTP_OK; - comm_write(sslState->client.fd, conn_established, strlen(conn_established), - sslConnectedWriteDone, sslState); -} - -static void -sslErrorComplete(int fdnotused, void *data, size_t sizenotused) -{ - SslStateData *sslState = (SslStateData *)data; - assert(sslState != NULL); - if (sslState->client.fd > -1) - comm_close(sslState->client.fd); - if (sslState->server.fd > -1) - comm_close(sslState->server.fd); -} - - -static void -sslConnectDone(int fdnotused, comm_err_t status, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - request_t *request = sslState->request; - ErrorState *err = NULL; - if (sslState->servers->_peer) - hierarchyNote(&sslState->request->hier, sslState->servers->code, - sslState->servers->_peer->host); - else if (Config.onoff.log_ip_on_direct) - hierarchyNote(&sslState->request->hier, sslState->servers->code, - fd_table[sslState->server.fd].ipaddr); - else - hierarchyNote(&sslState->request->hier, sslState->servers->code, - sslState->host); - if (status == COMM_ERR_DNS) { - debug(26, 4) ("sslConnect: Unknown host: %s\n", sslState->host); - err = errorCon(ERR_DNS_FAIL, HTTP_NOT_FOUND); - *sslState->status_ptr = HTTP_NOT_FOUND; - err->request = requestLink(request); - err->dnsserver_msg = xstrdup(dns_error_message); - err->callback = sslErrorComplete; - err->callback_data = sslState; - errorSend(sslState->client.fd, err); - } else if (status != COMM_OK) { - err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE); - *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE; - err->xerrno = errno; - err->host = xstrdup(sslState->host); - err->port = sslState->port; - err->request = requestLink(request); - err->callback = sslErrorComplete; - err->callback_data = sslState; - errorSend(sslState->client.fd, err); - } else { - if (sslState->servers->_peer) - sslProxyConnected(sslState->server.fd, sslState); - else { - sslConnected(sslState->server.fd, sslState); - } - commSetTimeout(sslState->server.fd, - Config.Timeout.read, - sslTimeout, - sslState); -#if DELAY_POOLS - commSetDefer(sslState->server.fd, sslDeferServerRead, sslState); -#endif - } -} - -CBDATA_TYPE(SslStateData); -void -sslStart(clientHttpRequest * http, size_t * size_ptr, int *status_ptr) -{ - /* Create state structure. */ - SslStateData *sslState = NULL; - int sock; - ErrorState *err = NULL; - int answer; - int fd = http->conn->fd; - request_t *request = http->request; - char *url = http->uri; - /* - * client_addr == no_addr indicates this is an "internal" request - * from peer_digest.c, asn.c, netdb.c, etc and should always - * be allowed. yuck, I know. - */ - if (request->client_addr.s_addr != no_addr.s_addr) { - /* - * Check if this host is allowed to fetch MISSES from us (miss_access) - */ - ACLChecklist ch; - ch.src_addr = request->client_addr; - ch.my_addr = request->my_addr; - ch.my_port = request->my_port; - ch.request = request; - answer = aclCheckFast(Config.accessList.miss, &ch); - if (answer == 0) { - err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN); - *status_ptr = HTTP_FORBIDDEN; - err->request = requestLink(request); - err->src_addr = request->client_addr; - errorSend(fd, err); - return; - } - } - debug(26, 3) ("sslStart: '%s %s'\n", - RequestMethodStr[request->method], url); - statCounter.server.all.requests++; - statCounter.server.other.requests++; - /* Create socket. */ - sock = comm_openex(SOCK_STREAM, - 0, - getOutgoingAddr(request), - 0, - COMM_NONBLOCKING, - getOutgoingTOS(request), - url); - if (sock == COMM_ERROR) { - debug(26, 4) ("sslStart: Failed because we're out of sockets.\n"); - err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR); - *status_ptr = HTTP_INTERNAL_SERVER_ERROR; - err->xerrno = errno; - err->request = requestLink(request); - errorSend(fd, err); - return; - } - CBDATA_INIT_TYPE(SslStateData); - sslState = cbdataAlloc(SslStateData); -#if DELAY_POOLS - sslState->delayId = DelayId::DelayClient(http); -#endif - sslState->url = xstrdup(url); - sslState->request = requestLink(request); - sslState->size_ptr = size_ptr; - sslState->status_ptr = status_ptr; - sslState->client.fd = fd; - sslState->server.fd = sock; - sslState->server.buf = (char *)xmalloc(SQUID_TCP_SO_RCVBUF); - sslState->client.buf = (char *)xmalloc(SQUID_TCP_SO_RCVBUF); - comm_add_close_handler(sslState->server.fd, - sslServerClosed, - sslState); - comm_add_close_handler(sslState->client.fd, - sslClientClosed, - sslState); - commSetTimeout(sslState->client.fd, - Config.Timeout.lifetime, - sslTimeout, - sslState); - commSetTimeout(sslState->server.fd, - Config.Timeout.connect, - sslTimeout, - sslState); - peerSelect(request, - NULL, - sslPeerSelectComplete, - sslState); - /* - * Disable the client read handler until peer selection is complete - * Take control away from client_side.c. - */ - commSetSelect(sslState->client.fd, COMM_SELECT_READ, NULL, NULL, 0); -} - -static void -sslProxyConnected(int fd, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - MemBuf mb; - HttpHeader hdr_out; - Packer p; - http_state_flags flags; - debug(26, 3) ("sslProxyConnected: FD %d sslState=%p\n", fd, sslState); - memset(&flags, '\0', sizeof(flags)); - flags.proxying = sslState->request->flags.proxying; - memBufDefInit(&mb); - memBufPrintf(&mb, "CONNECT %s HTTP/1.0\r\n", sslState->url); - httpBuildRequestHeader(sslState->request, - sslState->request, - NULL, /* StoreEntry */ - &hdr_out, - flags); /* flags */ - packerToMemInit(&p, &mb); - httpHeaderPackInto(&hdr_out, &p); - httpHeaderClean(&hdr_out); - packerClean(&p); - memBufAppend(&mb, "\r\n", 2); - - comm_old_write_mbuf(sslState->server.fd, mb, sslProxyConnectedWriteDone, sslState); - - commSetTimeout(sslState->server.fd, - Config.Timeout.read, - sslTimeout, - sslState); -} - -static void -sslPeerSelectComplete(FwdServer * fs, void *data) -{ - SslStateData *sslState = (SslStateData *)data; - request_t *request = sslState->request; - peer *g = NULL; - if (fs == NULL) { - ErrorState *err; - err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE); - *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE; - err->request = requestLink(sslState->request); - err->callback = sslErrorComplete; - err->callback_data = sslState; - errorSend(sslState->client.fd, err); - return; - } - sslState->servers = fs; - sslState->host = fs->_peer ? fs->_peer->host : request->host; - if (fs->_peer == NULL) { - sslState->port = request->port; - } else if (fs->_peer->http_port != 0) { - sslState->port = fs->_peer->http_port; - } else if ((g = peerFindByName(fs->_peer->host))) { - sslState->port = g->http_port; - } else { - sslState->port = CACHE_HTTP_PORT; - } - if (fs->_peer) { - sslState->request->peer_login = fs->_peer->login; - sslState->request->flags.proxying = 1; - } else { - sslState->request->peer_login = NULL; - sslState->request->flags.proxying = 0; - } -#if DELAY_POOLS - /* no point using the delayIsNoDelay stuff since ssl is nice and simple */ - if (g && g->options.no_delay && sslState->delayId) { - sslState->delayId = DelayId(); - } -#endif - commConnectStart(sslState->server.fd, - sslState->host, - sslState->port, - sslConnectDone, - sslState); -}