--------------------- PatchSet 6424 Date: 2005/02/12 11:16:57 Author: hno Branch: ssl-2_5 Tag: (none) Log: SSL shutdown notification support cleaned up Race windows on pending data fixed by making sure we try to read until SSL_read() indicates it needs network I/O. SSL_pending() is not reliable. Members: src/client_side.c:1.47.2.21.2.22->1.47.2.21.2.23 src/comm.c:1.18.6.2.8.4->1.18.6.2.8.5 src/ssl_support.c:1.6.6.1.2.13->1.6.6.1.2.14 Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.47.2.21.2.22 retrieving revision 1.47.2.21.2.23 diff -u -r1.47.2.21.2.22 -r1.47.2.21.2.23 --- squid/src/client_side.c 12 Feb 2005 10:32:36 -0000 1.47.2.21.2.22 +++ squid/src/client_side.c 12 Feb 2005 11:16:57 -0000 1.47.2.21.2.23 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.47.2.21.2.22 2005/02/12 10:32:36 hno Exp $ + * $Id: client_side.c,v 1.47.2.21.2.23 2005/02/12 11:16:57 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -3557,6 +3557,7 @@ } /* NOTREACHED */ } + fd_table[fd].read_pending = COMM_PENDING_NOW; if (SSL_session_reused(ssl)) { debug(83, 2) ("clientNegotiateSSL: Session %p reused on FD %d (%s:%d)\n", SSL_get_session(ssl), fd, fd_table[fd].ipaddr, (int)fd_table[fd].remote_port); } else { Index: squid/src/comm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm.c,v retrieving revision 1.18.6.2.8.4 retrieving revision 1.18.6.2.8.5 diff -u -r1.18.6.2.8.4 -r1.18.6.2.8.5 --- squid/src/comm.c 22 Oct 2004 13:52:35 -0000 1.18.6.2.8.4 +++ squid/src/comm.c 12 Feb 2005 11:16:59 -0000 1.18.6.2.8.5 @@ -1,6 +1,6 @@ /* - * $Id: comm.c,v 1.18.6.2.8.4 2004/10/22 13:52:35 hno Exp $ + * $Id: comm.c,v 1.18.6.2.8.5 2005/02/12 11:16:59 hno Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -655,28 +655,61 @@ void comm_reset_close(int fd) { + fde *F = &fd_table[fd]; struct linger L; L.l_onoff = 1; L.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0) debug(50, 0) ("commResetTCPClose: FD %d: %s\n", fd, xstrerror()); - fd_table[fd].flags.close_request = 1; + F->flags.close_request = 1; comm_close(fd); } +static inline void +comm_close_finish(int fd) +{ + fd_close(fd); /* update fdstat */ + close(fd); + statCounter.syscalls.sock.closes++; +} + +static inline void +comm_close_ssl_finish(int fd) +{ + fde *F = &fd_table[fd]; + SSL_free(F->ssl); + F->ssl = NULL; + comm_close_finish(fd); +} + +static void +comm_close_ssl(int fd, void *unused) +{ + fde *F = &fd_table[fd]; + int ret = ssl_shutdown_method(fd); + if (ret <= 0 && F->write_pending) { + commSetSelect(fd, COMM_SELECT_WRITE, comm_close_ssl, NULL, 0); + return; + } + comm_close_ssl_finish(fd); +} + +static void +comm_close_ssl_timeout(int fd, void *unused) +{ + debug(50, 1) ("comm_close_ssl: FD %d: timeout\n", fd); + comm_close_ssl_finish(fd); +} + void comm_close(int fd) { - fde *F = NULL; + fde *F = &fd_table[fd]; debug(5, 5) ("comm_close: FD %d\n", fd); assert(fd >= 0); assert(fd < Squid_MaxFD); - F = &fd_table[fd]; - /* XXX This needs to be split and also called once on lingering close. - * In addition the ssl_shutdown may need to wait - */ if (F->flags.closing) return; if (shutting_down && (!F->flags.open || F->type == FD_FILE)) @@ -684,10 +717,6 @@ assert(F->flags.open); assert(F->type != FD_FILE); F->flags.closing = 1; -#if USE_SSL - if (F->ssl) - ssl_shutdown_method(fd); -#endif CommWriteStateCallbackAndFree(fd, COMM_ERR_CLOSING); commCallCloseHandlers(fd); if (F->uses) /* assume persistent connect count */ @@ -695,13 +724,17 @@ #if USE_SSL if (F->ssl) { SSL *ssl = F->ssl; - SSL_free(ssl); - F->ssl = NULL; + if (!F->flags.close_request) { + F->flags.close_request = 1; + commSetTimeout(fd, 10, comm_close_ssl_timeout, NULL); + comm_close_ssl(fd, NULL); + return; + } + comm_close_ssl_finish(fd); + return; } #endif - fd_close(fd); /* update fdstat */ - close(fd); - statCounter.syscalls.sock.closes++; + comm_close_finish(fd); } /* Send a udp datagram to specified TO_ADDR. */ Index: squid/src/ssl_support.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/ssl_support.c,v retrieving revision 1.6.6.1.2.13 retrieving revision 1.6.6.1.2.14 diff -u -r1.6.6.1.2.13 -r1.6.6.1.2.14 --- squid/src/ssl_support.c 2 Dec 2004 00:53:42 -0000 1.6.6.1.2.13 +++ squid/src/ssl_support.c 12 Feb 2005 11:16:59 -0000 1.6.6.1.2.14 @@ -703,9 +703,9 @@ i = SSL_read(ssl, buf, len); + fd_table[fd].read_pending = COMM_PENDING_NOW; if (i > 0 && SSL_pending(ssl) > 0) { debug(83, 2) ("SSL fd %d is pending\n", fd); - fd_table[fd].read_pending = COMM_PENDING_NOW; } else if (i <= 0) { int err = SSL_get_error(ssl, i); switch (err) { @@ -714,6 +714,7 @@ i = 0; break; case SSL_ERROR_WANT_READ: + fd_table[fd].read_pending = COMM_PENDING_WANTS_READ; i = -1; errno = EAGAIN; break; @@ -768,6 +769,7 @@ errno = EAGAIN; break; case SSL_ERROR_WANT_WRITE: + fd_table[fd].write_pending = COMM_PENDING_WANTS_WRITE; i = -1; errno = EAGAIN; break;