Index: ChangeLog ================================================================== --- ChangeLog +++ ChangeLog @@ -1,5 +1,11 @@ +2000-06-05 Brent Welch + + * tls.c, tlsIO.c: Split Tls_Free into Tls_Clean, which does + the SSL cleanup, and the Tcl_Free call. It is important to shutdown + the SSL state "synchronously" during a stacked flush. + 2000-06-01 Scott Stanton * tlsIO.c: Restored call to Tcl_NotifyChannel from ChannelHandler to ensure that events propagate from the lower driver. This may result in an infinite loop in some cases, so this is not a total Index: tls.c ================================================================== --- tls.c +++ tls.c @@ -1,9 +1,9 @@ /* * Copyright (C) 1997-1999 Matt Newman * - * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.c,v 1.3 2000/05/04 20:40:40 aborr Exp $ + * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.c,v 1.4 2000/06/05 18:09:53 welch Exp $ * * TLS (aka SSL) Channel - can be layered on any bi-directional * Tcl_Channel (Note: Requires Trf Core Patch) * * This was built (almost) from scratch based upon observation of @@ -726,11 +726,12 @@ statePtr->self = chan; Tcl_StackChannel( interp, Tls_ChannelType(), (ClientData) statePtr, (TCL_READABLE | TCL_WRITABLE), chan); #endif if (statePtr->self == (Tcl_Channel) NULL) { - Tcl_EventuallyFree( (ClientData)statePtr, Tls_Free); + Tls_Free(statePtr); +/* Tcl_EventuallyFree( (ClientData)statePtr, Tls_Free); */ return TCL_ERROR; } /* allocate script */ if (script) { @@ -754,11 +755,12 @@ if (!statePtr->ssl) { /* SSL library error */ Tcl_AppendResult(interp, "couldn't construct ssl session: ", REASON(), (char *) NULL); - Tcl_EventuallyFree( (ClientData)statePtr, Tls_Free); + Tls_Free(statePtr); +/* Tcl_EventuallyFree( (ClientData)statePtr, Tls_Free); */ return TCL_ERROR; } /* * SSL Callbacks @@ -1029,22 +1031,53 @@ void Tls_Free( char *blockPtr ) { State *statePtr = (State *)blockPtr; + Tls_Clean(blockPtr); + Tcl_Free((char *)statePtr); +} + +/* + *------------------------------------------------------------------- + * + * Tls_Clean -- + * + * This procedure cleans up when a SSL socket based channel + * is closed and its reference count falls below 1. This should + * be called synchronously by the CloseProc, not in the + * EventuallyFree callback. + * + * Results: + * none + * + * Side effects: + * Frees all the state + * + *------------------------------------------------------------------- + */ +void +Tls_Clean( char *blockPtr ) +{ + State *statePtr = (State *)blockPtr; + /* we're assuming here that we're single-threaded */ if (statePtr->ssl) { SSL_shutdown(statePtr->ssl); SSL_free(statePtr->ssl); + statePtr->ssl = NULL; } - if (statePtr->callback) + if (statePtr->callback) { Tcl_DecrRefCount(statePtr->callback); + statePtr->callback = NULL; + } - if (statePtr->timer != (Tcl_TimerToken)NULL) + if (statePtr->timer != (Tcl_TimerToken)NULL) { Tcl_DeleteTimerHandler (statePtr->timer); + statePtr->timer = NULL; + } - Tcl_Free((char *)statePtr); } /* *------------------------------------------------------------------- * Index: tlsIO.c ================================================================== --- tlsIO.c +++ tlsIO.c @@ -1,9 +1,9 @@ /* * Copyright (C) 1997-2000 Matt Newman * - * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tlsIO.c,v 1.6 2000/06/02 05:14:46 welch Exp $ + * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tlsIO.c,v 1.7 2000/06/05 18:09:54 welch Exp $ * * TLS (aka SSL) Channel - can be layered on any bi-directional * Tcl_Channel (Note: Requires Trf Core Patch) * * This was built from scratch based upon observation of OpenSSL 0.9.2B @@ -140,10 +140,11 @@ if (statePtr->timer != (Tcl_TimerToken)NULL) { Tcl_DeleteTimerHandler (statePtr->timer); statePtr->timer = (Tcl_TimerToken)NULL; } + Tls_Clean(statePtr); Tcl_EventuallyFree( (ClientData)statePtr, Tls_Free); return TCL_OK; } /*