📄 ssl.c
字号:
/* * $Id: ssl.c,v 1.92.2.3 1999/07/07 01:52:53 wessels Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from the * Internet community. Development is led by Duane Wessels of the * National Laboratory for Applied Network Research and funded by the * National Science Foundation. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please 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"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 */#if DELAY_POOLS delay_id delay_id;#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 PF sslReadClient;static PF sslReadServer;static PF sslTimeout;static PF sslWriteClient;static PF sslWriteServer;static PSC sslPeerSelectComplete;static void sslStateFree(SslStateData * sslState);static void sslConnected(int fd, void *);static void sslProxyConnected(int fd, void *);static void sslSetSelect(SslStateData * sslState);#if DELAY_POOLSstatic DEFER sslDeferServerRead;#endifstatic voidsslServerClosed(int fd, void *data){ SslStateData *sslState = 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 voidsslClientClosed(int fd, void *data){ SslStateData *sslState = 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 voidsslStateFree(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;#if DELAY_POOLS delayUnregisterDelayIdPtr(&sslState->delay_id);#endif cbdataFree(sslState);}#if DELAY_POOLSstatic intsslDeferServerRead(int fdnotused, void *data){ SslStateData *s = data; return delayBytesWanted(s->delay_id, 0, 1) == 0;}#endifstatic voidsslSetSelect(SslStateData * sslState){ size_t read_sz = SQUID_TCP_SO_RCVBUF; assert(sslState->server.fd > -1 || sslState->client.fd > -1); if (sslState->client.fd > -1) { if (sslState->server.len > 0) { commSetSelect(sslState->client.fd, COMM_SELECT_WRITE, sslWriteClient, sslState, 0); } if (sslState->client.len < read_sz) { commSetSelect(sslState->client.fd, COMM_SELECT_READ, sslReadClient, sslState, Config.Timeout.read); } } else if (sslState->client.len == 0) { comm_close(sslState->server.fd); } if (sslState->server.fd > -1) { if (sslState->client.len > 0) { commSetSelect(sslState->server.fd, COMM_SELECT_WRITE, sslWriteServer, sslState, 0); }#if DELAY_POOLS /* If this was allowed to return 0, there would be a possibility * of the socket becoming "hung" with data accumulating but no * write handler (server.len==0) and no read handler (!(0<0)) and * no data flowing in the other direction. Hence the argument of * 1 as min. */ read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz);#endif if (sslState->server.len < read_sz) { /* Have room to read more */ commSetSelect(sslState->server.fd, COMM_SELECT_READ, sslReadServer, sslState, Config.Timeout.read); } } else if (sslState->client.fd == -1) { /* client already closed, nothing more to do */ } else if (sslState->server.len == 0) { comm_close(sslState->client.fd); }}/* Read from server side and queue it for writing to the client */static voidsslReadServer(int fd, void *data){ SslStateData *sslState = data; int len; size_t read_sz = SQUID_TCP_SO_RCVBUF - sslState->server.len; assert(fd == sslState->server.fd); debug(26, 3) ("sslReadServer: FD %d, reading %d bytes at offset %d\n", fd, read_sz, sslState->server.len); errno = 0;#if DELAY_POOLS read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz);#endif Counter.syscalls.sock.reads++; len = read(fd, sslState->server.buf + sslState->server.len, read_sz); debug(26, 3) ("sslReadServer: FD %d, read %d bytes\n", fd, len); if (len > 0) { fd_bytes(fd, len, FD_READ);#if DELAY_POOLS delayBytesIn(sslState->delay_id, len);#endif kb_incr(&Counter.server.all.kbytes_in, len); kb_incr(&Counter.server.other.kbytes_in, len); sslState->server.len += len; } cbdataLock(sslState); if (len < 0) { debug(50, 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); } if (cbdataValid(sslState)) sslSetSelect(sslState); cbdataUnlock(sslState);}/* Read from client side and queue it for writing to the server */static voidsslReadClient(int fd, void *data){ SslStateData *sslState = data; int len; assert(fd == sslState->client.fd); debug(26, 3) ("sslReadClient: FD %d, reading %d bytes at offset %d\n", fd, SQUID_TCP_SO_RCVBUF - sslState->client.len, sslState->client.len); Counter.syscalls.sock.reads++; len = read(fd, sslState->client.buf + sslState->client.len, SQUID_TCP_SO_RCVBUF - sslState->client.len); debug(26, 3) ("sslReadClient: FD %d, read %d bytes\n", fd, len); if (len > 0) { fd_bytes(fd, len, FD_READ); kb_incr(&Counter.client_http.kbytes_in, len); sslState->client.len += len; } cbdataLock(sslState); if (len < 0) { debug(50, 1) ("sslReadClient: FD %d: read failure: %s\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); } else if (len == 0) { comm_close(fd); } if (cbdataValid(sslState)) sslSetSelect(sslState); cbdataUnlock(sslState);}/* Writes data from the client buffer to the server side */static voidsslWriteServer(int fd, void *data){ SslStateData *sslState = data; int len; assert(fd == sslState->server.fd); debug(26, 3) ("sslWriteServer: FD %d, %d bytes to write\n", fd, sslState->client.len); Counter.syscalls.sock.writes++; len = write(fd, sslState->client.buf, sslState->client.len); debug(26, 3) ("sslWriteServer: FD %d, %d bytes written\n", fd, len); if (len > 0) { fd_bytes(fd, len, FD_WRITE); kb_incr(&Counter.server.all.kbytes_out, len); kb_incr(&Counter.server.other.kbytes_out, len); assert(len <= sslState->client.len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -