Check-in [8b2b046ff5]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added a flag for fastpath so that errors can be found while using it
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip-fix-io-layer
Files: files | file ages | folders
SHA1:8b2b046ff52e726019a66add72650063a690444a
User & Date: rkeene 2016-12-11 23:57:25
Context
2016-12-12
01:13
Updated debugging printf() calls to write to a temporary buffer so that multiple calls are not mixed up when writing check-in: 4c6adaabfc user: rkeene tags: wip-fix-io-layer
2016-12-11
23:57
Added a flag for fastpath so that errors can be found while using it check-in: 8b2b046ff5 user: rkeene tags: wip-fix-io-layer
21:22
Rewrote state engine for OpenSSL connection establishment to be more easily reasoned about check-in: 77e904c4e2 user: rkeene tags: wip-fix-io-layer
Changes

Changes to tlsBIO.c.

    67     67   	}
    68     68   
    69     69   #ifdef TCLTLS_SSL_USE_FASTPATH
    70     70   	/*
    71     71   	 * If the channel can be mapped back to a file descriptor, just use the file descriptor
    72     72   	 * with the SSL library since it will likely be optimized for this.
    73     73   	 */
    74         -	parentChannel = Tls_GetParent(statePtr);
           74  +	parentChannel = Tls_GetParent(statePtr, 0);
    75     75   	parentChannelType = Tcl_GetChannelType(parentChannel);
    76     76   
    77     77   	validParentChannelFd = 0;
    78     78   	if (strcmp(parentChannelType->typeName, "tcp") == 0) {
    79     79   		tclGetChannelHandleRet = Tcl_GetChannelHandle(parentChannel, TCL_READABLE, (ClientData) &parentChannelFdIn_p);
    80     80   		if (tclGetChannelHandleRet == TCL_OK) {
    81     81   			tclGetChannelHandleRet = Tcl_GetChannelHandle(parentChannel, TCL_WRITABLE, (ClientData) &parentChannelFdOut_p);
................................................................................
    89     89   			}
    90     90   		}
    91     91   	}
    92     92   
    93     93   	if (validParentChannelFd) {
    94     94   		dprintf("We found a shortcut, this channel is backed by a file descriptor: %i", parentChannelFdIn);
    95     95   		bio = BIO_new_socket(parentChannelFd, flags);
           96  +		statePtr->flags |= TLS_TCL_FASTPATH;
    96     97   		return(bio);
    97     98   	}
    98     99   
    99    100   	dprintf("Falling back to Tcl I/O for this channel");
   100    101   #endif
   101    102   
   102    103   	bio = BIO_new(BioMethods);
................................................................................
   108    109   }
   109    110   
   110    111   static int BioWrite(BIO *bio, CONST char *buf, int bufLen) {
   111    112   	Tcl_Channel chan;
   112    113   	int ret;
   113    114   	int tclEofChan;
   114    115   
   115         -	chan = Tls_GetParent((State *) BIO_get_data(bio));
          116  +	chan = Tls_GetParent((State *) BIO_get_data(bio), 0);
   116    117   
   117    118   	dprintf("[chan=%p] BioWrite(%p, <buf>, %d)", (void *)chan, (void *) bio, bufLen);
   118    119   
   119    120   	ret = Tcl_WriteRaw(chan, buf, bufLen);
   120    121   
   121    122   	tclEofChan = Tcl_Eof(chan);
   122    123   
................................................................................
   143    144   }
   144    145   
   145    146   static int BioRead(BIO *bio, char *buf, int bufLen) {
   146    147   	Tcl_Channel chan;
   147    148   	int ret = 0;
   148    149   	int tclEofChan;
   149    150   
   150         -	chan = Tls_GetParent((State *) BIO_get_data(bio));
          151  +	chan = Tls_GetParent((State *) BIO_get_data(bio), 0);
   151    152   
   152    153   	dprintf("[chan=%p] BioRead(%p, <buf>, %d)", (void *) chan, (void *) bio, bufLen);
   153    154   
   154    155   	if (buf == NULL) {
   155    156   		return 0;
   156    157   	}
   157    158   
................................................................................
   195    196   	return BioWrite(bio, str, (int) strlen(str));
   196    197   }
   197    198   
   198    199   static long BioCtrl(BIO *bio, int cmd, long num, void *ptr) {
   199    200   	Tcl_Channel chan;
   200    201   	long ret = 1;
   201    202   
   202         -	chan = Tls_GetParent((State *) BIO_get_data(bio));
          203  +	chan = Tls_GetParent((State *) BIO_get_data(bio), 0);
   203    204   
   204    205   	dprintf("BioCtrl(%p, 0x%x, 0x%x, %p)", (void *) bio, (unsigned int) cmd, (unsigned int) num, (void *) ptr);
   205    206   
   206    207   	switch (cmd) {
   207    208   		case BIO_CTRL_RESET:
   208    209   			dprintf("Got BIO_CTRL_RESET");
   209    210   			num = 0;

Changes to tlsIO.c.

   418    418   					 * NULL to get all options and
   419    419   					 * their values. */
   420    420   	Tcl_DString *dsPtr)		/* Where to store the computed value
   421    421   					 * initialized by caller. */
   422    422   {
   423    423       State *statePtr = (State *) instanceData;
   424    424   
   425         -   Tcl_Channel downChan = Tls_GetParent(statePtr);
          425  +   Tcl_Channel downChan = Tls_GetParent(statePtr, TLS_TCL_FASTPATH);
   426    426      Tcl_DriverGetOptionProc *getOptionProc;
   427    427   
   428    428       getOptionProc = Tcl_ChannelGetOptionProc(Tcl_GetChannelType(downChan));
   429    429       if (getOptionProc != NULL) {
   430    430           return (*getOptionProc)(Tcl_GetChannelInstanceData(downChan), interp, optionName, dsPtr);
   431    431       } else if (optionName == (char*) NULL) {
   432    432           /*
................................................................................
   473    473       if (statePtr->flags & TLS_TCL_CALLBACK) {
   474    474           dprintf("Callback is on-going, doing nothing");
   475    475           return;
   476    476       }
   477    477   
   478    478       dprintFlags(statePtr);
   479    479   
   480         -    downChan = Tls_GetParent(statePtr);
          480  +    downChan = Tls_GetParent(statePtr, TLS_TCL_FASTPATH);
   481    481   
   482    482       if (statePtr->flags & TLS_TCL_HANDSHAKE_FAILED) {
   483    483           dprintf("Asked to watch a socket with a failed handshake -- nothing can happen here");
   484    484   
   485    485   	dprintf("Unregistering interest in the lower channel");
   486    486   	(Tcl_GetChannelType(downChan))->watchProc(Tcl_GetChannelInstanceData(downChan), 0);
   487    487   
................................................................................
   538    538    *	The appropriate Tcl_File or NULL if not present. 
   539    539    *
   540    540    * Side effects:
   541    541    *	None.
   542    542    *
   543    543    *-------------------------------------------------------------------
   544    544    */
   545         -static int
   546         -TlsGetHandleProc(ClientData instanceData,	/* The socket state. */
   547         -                 int direction,		/* Which Tcl_File to retrieve? */
   548         -                 ClientData *handlePtr)	/* Where to store the handle.  */
   549         -{
   550         -    State *statePtr = (State *) instanceData;
          545  +static int TlsGetHandleProc(ClientData instanceData, int direction, ClientData *handlePtr) {
          546  +	State *statePtr = (State *) instanceData;
   551    547   
   552         -    return Tcl_GetChannelHandle(Tls_GetParent(statePtr), direction, handlePtr);
          548  +	return(Tcl_GetChannelHandle(Tls_GetParent(statePtr, TLS_TCL_FASTPATH), direction, handlePtr));
   553    549   }
   554    550   
   555    551   /*
   556    552    *-------------------------------------------------------------------
   557    553    *
   558    554    * TlsNotifyProc --
   559    555    *
................................................................................
   565    561    *
   566    562    * Side effects:
   567    563    *	May process the incoming event by itself.
   568    564    *
   569    565    *-------------------------------------------------------------------
   570    566    */
   571    567   
   572         -static int
   573         -TlsNotifyProc(instanceData, mask)
   574         -    ClientData	   instanceData; /* The state of the notified transformation */
   575         -    int		   mask;       /* The mask of occuring events */
   576         -{
          568  +static int TlsNotifyProc(ClientData instanceData, int mask) {
   577    569       State *statePtr = (State *) instanceData;
   578    570   
   579    571       /*
   580    572        * An event occured in the underlying channel.  This
   581    573        * transformation doesn't process such events thus returns the
   582    574        * incoming mask unchanged.
   583    575        */
................................................................................
   883    875   		}
   884    876   	}
   885    877   
   886    878   	*errorCodePtr = 0;
   887    879   	return(0);
   888    880   }
   889    881   
   890         -Tcl_Channel Tls_GetParent(State *statePtr) {
          882  +Tcl_Channel Tls_GetParent(State *statePtr, int maskFlags) {
   891    883   	dprintf("Requested to get parent of channel %p", statePtr->self);
          884  +
          885  +	if ((statePtr->flags & ~maskFlags) & TLS_TCL_FASTPATH) {
          886  +		dprintf("Asked to get the parent channel while we are using FastPath -- returning NULL");
          887  +		return(NULL);
          888  +	}
   892    889   
   893    890   	return(Tcl_GetStackedChannel(statePtr->self));
   894    891   }

Changes to tlsInt.h.

    86     86                                   fprintf(stderr, "%s:%i:%s():%s->flags=0", __FILE__, __LINE__, __func__, #statePtr); \
    87     87                                   if (((statePtr)->flags & TLS_TCL_ASYNC) == TLS_TCL_ASYNC) { fprintf(stderr,"|TLS_TCL_ASYNC"); }; \
    88     88                                   if (((statePtr)->flags & TLS_TCL_SERVER) == TLS_TCL_SERVER) { fprintf(stderr,"|TLS_TCL_SERVER"); }; \
    89     89                                   if (((statePtr)->flags & TLS_TCL_INIT) == TLS_TCL_INIT) { fprintf(stderr,"|TLS_TCL_INIT"); }; \
    90     90                                   if (((statePtr)->flags & TLS_TCL_DEBUG) == TLS_TCL_DEBUG) { fprintf(stderr,"|TLS_TCL_DEBUG"); }; \
    91     91                                   if (((statePtr)->flags & TLS_TCL_CALLBACK) == TLS_TCL_CALLBACK) { fprintf(stderr,"|TLS_TCL_CALLBACK"); }; \
    92     92                                   if (((statePtr)->flags & TLS_TCL_HANDSHAKE_FAILED) == TLS_TCL_HANDSHAKE_FAILED) { fprintf(stderr,"|TLS_TCL_HANDSHAKE_FAILED"); }; \
           93  +                                if (((statePtr)->flags & TLS_TCL_FASTPATH) == TLS_TCL_FASTPATH) { fprintf(stderr,"|TLS_TCL_FASTPATH"); }; \
    93     94                                   fprintf(stderr, "\n"); \
    94     95                                 }
    95     96   #else
    96     97   #define dprintf(...) if (0) { fprintf(stderr, __VA_ARGS__); }
    97     98   #define dprintBuffer(bufferName, bufferLength) /**/
    98     99   #define dprintFlags(statePtr) /**/
    99    100   #endif
................................................................................
   112    113   #define TLS_TCL_INIT	(1<<2)	/* Initializing connection */
   113    114   #define TLS_TCL_DEBUG	(1<<3)	/* Show debug tracing */
   114    115   #define TLS_TCL_CALLBACK	(1<<4)	/* In a callback, prevent update
   115    116   					 * looping problem. [Bug 1652380] */
   116    117   #define TLS_TCL_HANDSHAKE_FAILED (1<<5) /* Set on handshake failures and once
   117    118                                            * set, all further I/O will result
   118    119                                            * in ECONNABORTED errors. */
   119         -
          120  +#define TLS_TCL_FASTPATH (1<<6)         /* The parent channel is being used directly by the SSL library */
   120    121   #define TLS_TCL_DELAY (5)
   121    122   
   122    123   /*
   123    124    * This structure describes the per-instance state
   124    125    * of an ssl channel.
   125    126    *
   126    127    * The SSL processing context is maintained here, in the ClientData
................................................................................
   152    153   #endif /* Tcl_GetStackedChannel */
   153    154   #endif /* USE_TCL_STUBS */
   154    155   
   155    156   /*
   156    157    * Forward declarations
   157    158    */
   158    159   Tcl_ChannelType *Tls_ChannelType(void);
   159         -Tcl_Channel     Tls_GetParent(State *statePtr);
          160  +Tcl_Channel     Tls_GetParent(State *statePtr, int maskFlags);
   160    161   
   161    162   Tcl_Obj         *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert);
   162    163   void            Tls_Error(State *statePtr, char *msg);
   163    164   void            Tls_Free(char *blockPtr);
   164    165   void            Tls_Clean(State *statePtr);
   165    166   int             Tls_WaitForConnect(State *statePtr, int *errorCodePtr);
   166    167   
   167    168   BIO             *BIO_new_tcl(State* statePtr, int flags);
   168    169   
   169    170   #define PTR2INT(x) ((int) ((intptr_t) (x)))
   170    171   
   171    172   #endif /* _TLSINT_H */