I'm still looking into this and I'm still just confused.  There is a small
bug on line 1731 of sslcontext.c (CVS).

       SSL_CTX_set_session_id_context(
           sslcontext->sslctx,
           (void *) &sslcontext->sessionCacheId,
           sizeof(sslcontext->sessionCacheId)
       );


That sizeof() should almost certainly be strlen (sessionCacheId is char *,
not char[]), but I don't think thats really causing any of my problems.

Here is a patch that exposes some of the openssl session cache statistics
collection functionality to the TCL layer.  I tend to get zero back from
everything in my test environment, so I get the feeling something is not
quite right with the session caching logic, but I still haven't found
anything substantial.  This page roughly describes what _should_ be
available.

http://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html

use like 'ns_openssl_sess_stats cache_hits default_ctx'.

-Andrew

Index: tclcmds.c
===================================================================
RCS file: /cvsroot/aolserver/nsopenssl/tclcmds.c,v
retrieving revision 1.51
diff -c -r1.51 tclcmds.c
*** tclcmds.c   13 Jun 2004 04:21:31 -0000      1.51
--- tclcmds.c   31 Jan 2007 02:48:55 -0000
***************
*** 138,144 ****
     NsTclOpenSSLSockListenObjCmd,
     NsTclOpenSSLSockListenCallbackObjCmd,
     NsTclOpenSSLSockCallbackObjCmd,
!     NsTclOpenSSLGetUrlObjCmd;

 extern Tcl_CmdProc
     NsTclOpenSSLGetUrlCmd,
--- 138,145 ----
     NsTclOpenSSLSockListenObjCmd,
     NsTclOpenSSLSockListenCallbackObjCmd,
     NsTclOpenSSLSockCallbackObjCmd,
!     NsTclOpenSSLGetUrlObjCmd,
!     NsTclOpenSSLSessStatsObjCmd;

 extern Tcl_CmdProc
     NsTclOpenSSLGetUrlCmd,
***************
*** 160,165 ****
--- 161,167 ----
     {"ns_openssl_socklisten",
NULL,                              NsTclOpenSSLSockListenObjCmd           },
     {"ns_openssl_sockcallback",
NULL,                              NsTclOpenSSLSockCallbackObjCmd         },
     {"ns_openssl_socklistencallback",
NULL,                              NsTclOpenSSLSockListenCallbackObjCmd   },
+     {"ns_openssl_sess_stats",
NULL,                              NsTclOpenSSLSessStatsObjCmd            },
 #if 0  /* these ns_openssl_sock* commands are not implemented */
     {"ns_openssl_socknread",          NsTclOpenSSLSockNReadCmd,
   NULL
},
     {"ns_openssl_sockselect",         NsTclOpenSSLSockSelectCmd,
NULL                                   },
***************
*** 1254,1259 ****
--- 1256,1358 ----
     return TCL_OK;
 }

+ /*
+  *----------------------------------------------------------------------
+  *
+  * NsTclOpenSSLSessStatsObjCmd --
+  *
+  *      Return per-context session statistics
+  *
+  * Results:
+  *      Tcl result.
+  *
+  * Side effects:
+  *      None.
+  *
+  *----------------------------------------------------------------------
+  */
+
+ int
+ NsTclOpenSSLSessStatsObjCmd(ClientData arg, Tcl_Interp *interp, int objc,
+         Tcl_Obj *CONST objv[])
+ {
+     static CONST char *opts[] = {
+         "number", "connect", "connect_good", "connect_renegotiate",
+         "accept", "accept_good", "accept_renegotiate", "cache_hits",
+         "cache_misses", "cache_full", "timeouts"
+     };
+
+     enum ISubCmdIdx {
+         CNumberIdx, CConnectIdx, CConnectGoodIdx, CConnectRenegotiateIdx,
+         CAcceptIdx, CAcceptGoodIdx, CAcceptRenegotiateIdx, CCacheHitsIdx,
+         CCacheMissesIdx, CCacheFullIdx, CTimeoutsIdx
+     } opt;
+
+     Server            *thisServer = (Server *) arg;
+     NsOpenSSLContext  *sslcontext = NULL;
+
+     if (objc < 2 || objc > 3) {
+         Tcl_WrongNumArgs(interp, 1, objv, "name ?sslcontext?");
+         return TCL_ERROR;
+     }
+
+     if (objc == 4) {
+         sslcontext = Ns_OpenSSLServerSSLContextGet(thisServer->server,
objv[2]);
+     } else {
+         sslcontext = NsOpenSSLContextClientDefaultGet(thisServer->server);
+     }
+
+     if (sslcontext == NULL) {
+         Tcl_SetResult(interp, "failed to use either named or default SSL
context",
+                 TCL_STATIC);
+         return TCL_ERROR;
+     }
+
+     if (Tcl_GetIndexFromObj(interp, objv[1], opts, "name", 0,
+                 (int *) &opt) != TCL_OK) {
+         return TCL_ERROR;
+     }
+
+     switch (opt) {
+         case CNumberIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_number(sslcontext->sslctx));
+             break;
+         case CConnectIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_connect(sslcontext->sslctx));
+             break;
+         case CConnectGoodIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_connect_good(sslcontext->sslctx));
+             break;
+         case CConnectRenegotiateIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_connect_renegotiate(sslcontext->sslctx));
+             break;
+         case CAcceptIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_accept(sslcontext->sslctx));
+             break;
+         case CAcceptGoodIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_accept_good(sslcontext->sslctx));
+             break;
+         case CAcceptRenegotiateIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_accept_renegotiate(sslcontext->sslctx));
+             break;
+         case CCacheHitsIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_hits(sslcontext->sslctx));
+             break;
+         case CCacheMissesIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_misses(sslcontext->sslctx));
+             break;
+         case CCacheFullIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_cache_full(sslcontext->sslctx));
+             break;
+         case CTimeoutsIdx:
+             sprintf(interp->result, "%ld",
SSL_CTX_sess_timeouts(sslcontext->sslctx));
+             break;
+     }
+
+     return TCL_OK;
+ }
+
+


 /*
  *----------------------------------------------------------------------


On 1/29/07, Scott Goodwin <[EMAIL PROTECTED]> wrote:

At this point I'd prefer not to speculate -- much better to replicate the
problem and see it in all its dynamic glory. However, my sense is that
session caching, keepalive and other factors may make the problem worse but
are not likely to be root causes.



/s.




On Jan 29, 2007, at 6:13 PM, Andrew Steets wrote:

I noticed that the default ssl session cache size is only 128, and the
default session timeout is five minutes.  If clients are not expiring the
session before 5 minutes, and you've got more than 128 clients in 5 minutes,
then what should happen?

The openssl documentation is a bit unclear:

 SSL_CTX_sess_set_cache_size(3):

 When the maximum number of sessions is reached, no more new sessions are
added to the cache. New space may be added by
calling  SSL_CTX_flush_sessions(3) to remove expired sessions.

 SSL_CTX_flush_sessions(3):

As sessions will not be reused ones they are expired, they should be
removed from the cache to save resources. This can either be done
automatically whenever 255 new sessions were established or manually by
calling SSL_CTX_flush_sessions().

And it doesn't look like nsopenssl ever calls SSL_CTX_flush_sessions()
explicitly.

So the default cache size is 128, but it only flushed after 255
sessions?  That sounds like trouble.  Has anyone tried increasing the
'sessioncachesize' parameter?

 Also, it looks like openssl tracks cache full events on a per-ctx basis,
but they aren't exposed in nsopenssl.  That might be nice to have in a
future rev.

-Andrew


On 1/29/07, Alex Kroman <[EMAIL PROTECTED]> wrote:
>  Hi all,
>
> I turned off keepalive on our production server but am still receiving
> the "bad write retry" errors.
>
> -Alex
>
> -----Original Message-----
> From: AOLserver Discussion [mailto: [EMAIL PROTECTED] On
Behalf
> Of Dossy Shiobara
> Sent: Friday, January 26, 2007 10:35 AM
> To: [email protected]
> Subject: Re: [AOLSERVER] SSL read error: bad write retry
>
> On 2007.01.26, Alex Kroman <[EMAIL PROTECTED]> wrote:
> > I had Siege connect to my development server 50,000 times and did not
> > receive the bad write retry once.  While clicking around the site with

>
> > Siege active I still got the "bad write retry" and a blank page in
> > about
> > 75 clicks.  This is a similar result to what I would get when my
> > development server is not under load.
>
> I smell SSLv2 at play here.  I bet Firefox is using TLS or SSLv3, while
> IE is still using SSLv2.
>
> What do your "protocols" and "ciphersuite" ns_param's look like in your
> nsopenssl config?
>
> -- Dossy
>
> --
> Dossy Shiobara              | [EMAIL PROTECTED] | http://dossy.org/
> Panoptic Computer Network   |  http://panoptic.com/
>   "He realized the fastest way to change is to laugh at your own
>     folly -- then you can let go and quickly move on." (p. 70)
>
>
> --
> AOLserver -  http://www.aolserver.com/
>
> To Remove yourself from this list, simply send an email to
> <[EMAIL PROTECTED]> with the body of "SIGNOFF AOLSERVER" in the
> email message. You can leave the Subject: field of your email blank.
>
>
> --
> AOLserver - http://www.aolserver.com/
>
> To Remove yourself from this list, simply send an email to <
[EMAIL PROTECTED]> with the
> body of "SIGNOFF AOLSERVER" in the email message. You can leave the
Subject: field of your email blank.
>




--
AOLserver - http://www.aolserver.com/



To Remove yourself from this list, simply send an email to <
[EMAIL PROTECTED]> with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the
Subject: field of your email blank.






--
AOLserver - http://www.aolserver.com/



To Remove yourself from this list, simply send an email to <
[EMAIL PROTECTED]> with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the
Subject: field of your email blank.






--
AOLserver - http://www.aolserver.com/

To Remove yourself from this list, simply send an email to <[EMAIL PROTECTED]> 
with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: 
field of your email blank.

Reply via email to