Overview
Comment: | Added IO buffer checks to TlsChannelHandlerTimer mask function. Reordered TlsNotifyProc to check conditions prior to timer deletion. Pass buffer length in MessageCallback. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | main |
Files: | files | file ages | folders |
SHA3-256: |
6252a3a1f56de1c69f993bbaa539efd0 |
User & Date: | bohagan on 2024-12-29 04:36:20 |
Other Links: | branch diff | manifest | tags |
Context
2024-12-31
| ||
04:12 | More comment updates and changes for fast path option check-in: c61a46b561 user: bohagan tags: trunk, main | |
2024-12-29
| ||
04:36 | Added IO buffer checks to TlsChannelHandlerTimer mask function. Reordered TlsNotifyProc to check conditions prior to timer deletion. Pass buffer length in MessageCallback. check-in: 6252a3a1f5 user: bohagan tags: trunk, main | |
04:18 | Renamed BIO read/write functions to input/output to avoid confusion with API names. Added PKI and Certificates section to docs. Added/updated comments, formatting updates, etc. check-in: 3848af25d2 user: bohagan tags: trunk, main | |
Changes
Modified generic/tls.c
from [6556ea2daa]
to [1c80245128].
︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 | { State *statePtr = (State*)arg; Tcl_Interp *interp = statePtr->interp; Tcl_Obj *cmdPtr; char *ver, *type; BIO *bio; char buffer[15000]; buffer[0] = 0; dprintf("Called"); if (statePtr->callback == (Tcl_Obj*)NULL) { return; } | > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | { State *statePtr = (State*)arg; Tcl_Interp *interp = statePtr->interp; Tcl_Obj *cmdPtr; char *ver, *type; BIO *bio; char buffer[15000]; Tcl_Size blen = 0; buffer[0] = 0; dprintf("Called"); if (statePtr->callback == (Tcl_Obj*)NULL) { return; } |
︙ | ︙ | |||
296 297 298 299 300 301 302 | #endif default: type = "unknown"; } /* Needs compile time option "enable-ssl-trace". */ if ((bio = BIO_new(BIO_s_mem())) != NULL) { | < | | | | | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | #endif default: type = "unknown"; } /* Needs compile time option "enable-ssl-trace". */ if ((bio = BIO_new(BIO_s_mem())) != NULL) { SSL_trace(write_p, version, content_type, buf, len, ssl, (void *)bio); blen = (Tcl_Size) BIO_read(bio, buffer, BIO_pending(bio) < 15000 ? BIO_pending(bio) : 14999); blen = (blen<0) ? 0 : blen; buffer[blen] = 0; (void)BIO_flush(bio); BIO_free(bio); } dprintf("Message direction=%d, ver=%s, type=%s, message=%s", write_p, ver, type, &buffer[0]); /* Create command to eval with fn, chan, direction, version, type, and message args */ cmdPtr = Tcl_DuplicateObj(statePtr->callback); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj("message", -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(Tcl_GetChannelName(statePtr->self), -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(write_p ? "Sent" : "Received", -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(ver, -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(type, -1)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(buffer, blen)); /* Eval callback command */ Tcl_IncrRefCount(cmdPtr); EvalCallback(interp, statePtr, cmdPtr); Tcl_DecrRefCount(cmdPtr); } #endif |
︙ | ︙ | |||
2564 2565 2566 2567 2568 2569 2570 | /* connection state */ LAPPEND_STR(interp, objPtr, "state", SSL_state_string_long(ssl), -1); /* Get SNI requested server name */ LAPPEND_STR(interp, objPtr, "servername", SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name), -1); /* Report the selected protocol as a result of the negotiation */ | | | 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 | /* connection state */ LAPPEND_STR(interp, objPtr, "state", SSL_state_string_long(ssl), -1); /* Get SNI requested server name */ LAPPEND_STR(interp, objPtr, "servername", SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name), -1); /* Report the selected protocol as a result of the negotiation */ SSL_get0_alpn_selected(ssl, &proto, &ulen); LAPPEND_STR(interp, objPtr, "alpn", (char *)proto, (Tcl_Size) ulen); /* Get protocol */ LAPPEND_STR(interp, objPtr, "protocol", SSL_get_version(ssl), -1); /* Renegotiation allowed */ LAPPEND_BOOL(interp, objPtr, "renegotiation_allowed", SSL_get_secure_renegotiation_support((SSL *) ssl)); |
︙ | ︙ | |||
3100 3101 3102 3103 3104 3105 3106 | /* Remove list of ALPN protocols */ if (statePtr->protos) { ckfree(statePtr->protos); statePtr->protos = NULL; } | | | | 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 | /* Remove list of ALPN protocols */ if (statePtr->protos) { ckfree(statePtr->protos); statePtr->protos = NULL; } /* BIO_free() frees up a single BIO */ if (statePtr->bio) { /* This will call SSL_shutdown. Bug 1414045 */ dprintf("BIO_free(%p)", statePtr->bio); BIO_free(statePtr->bio); statePtr->bio = NULL; } /* Free SSL context and statePtr->p_bio */ if (statePtr->ssl) { dprintf("SSL_free(%p) and p_bio(%p)", statePtr->ssl, statePtr->p_bio); SSL_free(statePtr->ssl); |
︙ | ︙ |
Modified generic/tlsIO.c
from [0f8d7086c3]
to [a3e847176e].
︙ | ︙ | |||
982 983 984 985 986 987 988 | */ static void TlsChannelHandlerTimer( ClientData clientData) /* Socket state. */ { State *statePtr = (State *) clientData; int mask = statePtr->want; /* Init to SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE */ | | | | | | | | < < < | 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 | */ static void TlsChannelHandlerTimer( ClientData clientData) /* Socket state. */ { State *statePtr = (State *) clientData; int mask = statePtr->want; /* Init to SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE */ dprintf("Called with mask 0x%02x", mask); statePtr->timer = (Tcl_TimerToken) NULL; /* Check for amount of data pending in IO or BIO write buffer */ if (Tcl_OutputBuffered(statePtr->self) || BIO_wpending(statePtr->bio)) { dprintf("[chan=%p] BIO writable", statePtr->self); mask |= TCL_WRITABLE; } /* Check for amount of data pending in IO or BIO read buffer */ if (Tcl_InputBuffered(statePtr->self) || BIO_pending(statePtr->bio)) { dprintf("[chan=%p] BIO readable", statePtr->self); mask |= TCL_READABLE; } /* Notify the generic IO layer that mask events have occurred on the channel */ dprintf("Notifying ourselves with mask=%d", mask); Tcl_NotifyChannel(statePtr->self, mask); statePtr->want = 0; return; } /* *----------------------------------------------------------------------------- * * TlsWatchProc -- |
︙ | ︙ | |||
1079 1080 1081 1082 1083 1084 1085 | watchProc(Tcl_GetChannelInstanceData(parent), mask); /* Do we have any pending events */ pending = (statePtr->want || \ ((mask & TCL_READABLE) && ((Tcl_InputBuffered(statePtr->self) > 0) || (BIO_ctrl_pending(statePtr->bio) > 0))) || ((mask & TCL_WRITABLE) && ((Tcl_OutputBuffered(statePtr->self) > 0) || (BIO_ctrl_wpending(statePtr->bio) > 0)))); | | | | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | watchProc(Tcl_GetChannelInstanceData(parent), mask); /* Do we have any pending events */ pending = (statePtr->want || \ ((mask & TCL_READABLE) && ((Tcl_InputBuffered(statePtr->self) > 0) || (BIO_ctrl_pending(statePtr->bio) > 0))) || ((mask & TCL_WRITABLE) && ((Tcl_OutputBuffered(statePtr->self) > 0) || (BIO_ctrl_wpending(statePtr->bio) > 0)))); dprintf("IO Want=%d, input buffer=%d, output buffer=%d, BIO pending=%zd, BIO wpending=%zd, pending=%d", \ statePtr->want, Tcl_InputBuffered(statePtr->self), Tcl_OutputBuffered(statePtr->self), \ BIO_ctrl_pending(statePtr->bio), BIO_ctrl_wpending(statePtr->bio), pending); if (!(mask & TCL_READABLE) || pending == 0) { /* Remove timer, if any */ if (statePtr->timer != (Tcl_TimerToken) NULL) { dprintf("A timer was found, deleting it"); Tcl_DeleteTimerHandler(statePtr->timer); statePtr->timer = (Tcl_TimerToken) NULL; |
︙ | ︙ | |||
1153 1154 1155 1156 1157 1158 1159 | ClientData instanceData, /* Socket state. */ int mask) /* type of event that occurred: OR-ed * combination of TCL_READABLE or TCL_WRITABLE */ { State *statePtr = (State *) instanceData; int errorCode = 0; | | < < < < < < < < < < < < | > | 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 | ClientData instanceData, /* Socket state. */ int mask) /* type of event that occurred: OR-ed * combination of TCL_READABLE or TCL_WRITABLE */ { State *statePtr = (State *) instanceData; int errorCode = 0; dprintf("Called with mask 0x%02x", mask); /* Abort if the user verify callback is still running to avoid triggering * another call before the current one is complete. */ if (statePtr->flags & TLS_TCL_CALLBACK) { dprintf("Callback is on-going, returning failed"); return 0; } /* If not initialized, do connect */ if (statePtr->flags & TLS_TCL_INIT) { |
︙ | ︙ | |||
1192 1193 1194 1195 1196 1197 1198 | return 0; } dprintf("Tls_WaitForConnect returned an error"); } } | < > > > > > > > > > | > | | < > | 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 | return 0; } dprintf("Tls_WaitForConnect returned an error"); } } /* * Delete an existing timer. It was not fired, yet we are here, so the * channel below generated such an event and we don't have to. The renewal * of the interest after the execution of channel handlers will eventually * cause us to recreate the timer (in WatchProc). */ if (statePtr->timer != (Tcl_TimerToken) NULL) { Tcl_DeleteTimerHandler(statePtr->timer); statePtr->timer = (Tcl_TimerToken) NULL; } /* * An event occurred in the underlying channel. This transformation doesn't * process such events thus returns the incoming mask unchanged. */ dprintf("Returning %i", mask); return mask; } /* *----------------------------------------------------------------------------- * * Tls_ChannelType -- |
︙ | ︙ |