@@ -116,6 +116,11 @@ void TLSWrap::InitSSL() {
116116#endif   //  SSL_MODE_RELEASE_BUFFERS
117117
118118  SSL_set_app_data (ssl_.get (), this );
119+   //  Using InfoCallback isn't how we are supposed to check handshake progress:
120+   //    https://github.com/openssl/openssl/issues/7199#issuecomment-420915993
121+   // 
122+   //  Note on when this gets called on various openssl versions:
123+   //    https://github.com/openssl/openssl/issues/7199#issuecomment-420670544
119124  SSL_set_info_callback (ssl_.get (), SSLInfoCallback);
120125
121126  if  (is_server ()) {
@@ -194,6 +199,9 @@ void TLSWrap::Start(const FunctionCallbackInfo<Value>& args) {
194199
195200  //  Send ClientHello handshake
196201  CHECK (wrap->is_client ());
202+   //  Seems odd to read when when we want to send, but SSL_read() triggers a
203+   //  handshake if a session isn't established, and handshake will cause
204+   //  encrypted data to become available for output.
197205  wrap->ClearOut ();
198206  wrap->EncOut ();
199207}
@@ -243,7 +251,7 @@ void TLSWrap::EncOut() {
243251    return ;
244252
245253  //  Wait for `newSession` callback to be invoked
246-   if  (is_waiting_new_session ())
254+   if  (is_awaiting_new_session ())
247255    return ;
248256
249257  //  Split-off queue
@@ -253,7 +261,7 @@ void TLSWrap::EncOut() {
253261  if  (ssl_ == nullptr )
254262    return ;
255263
256-   //  No data  to write
264+   //  No encrypted output ready  to write to the underlying stream. 
257265  if  (BIO_pending (enc_out_) == 0 ) {
258266    if  (pending_cleartext_input_.empty ())
259267      InvokeQueued (0 );
@@ -442,13 +450,13 @@ void TLSWrap::ClearOut() {
442450}
443451
444452
445- bool  TLSWrap::ClearIn () {
453+ void  TLSWrap::ClearIn () {
446454  //  Ignore cycling data if ClientHello wasn't yet parsed
447455  if  (!hello_parser_.IsEnded ())
448-     return   false ;
456+     return ;
449457
450458  if  (ssl_ == nullptr )
451-     return   false ;
459+     return ;
452460
453461  std::vector<uv_buf_t > buffers;
454462  buffers.swap (pending_cleartext_input_);
@@ -468,8 +476,9 @@ bool TLSWrap::ClearIn() {
468476
469477  //  All written
470478  if  (i == buffers.size ()) {
479+     //  We wrote all the buffers, so no writes failed (written < 0 on failure).
471480    CHECK_GE (written, 0 );
472-     return   true ;
481+     return ;
473482  }
474483
475484  //  Error or partial write
@@ -481,6 +490,8 @@ bool TLSWrap::ClearIn() {
481490  Local<Value> arg = GetSSLError (written, &err, &error_str);
482491  if  (!arg.IsEmpty ()) {
483492    write_callback_scheduled_ = true ;
493+     //  XXX(sam) Should forward an error object with .code/.function/.etc, if
494+     //  possible.
484495    InvokeQueued (UV_EPROTO, error_str.c_str ());
485496  } else  {
486497    //  Push back the not-yet-written pending buffers into their queue.
@@ -491,7 +502,7 @@ bool TLSWrap::ClearIn() {
491502                                    buffers.end ());
492503  }
493504
494-   return   false ;
505+   return ;
495506}
496507
497508
@@ -547,6 +558,7 @@ void TLSWrap::ClearError() {
547558}
548559
549560
561+ //  Called by StreamBase::Write() to request async write of clear text into SSL.
550562int  TLSWrap::DoWrite (WriteWrap* w,
551563                     uv_buf_t * bufs,
552564                     size_t  count,
@@ -560,18 +572,26 @@ int TLSWrap::DoWrite(WriteWrap* w,
560572  }
561573
562574  bool  empty = true ;
563- 
564-   //  Empty writes should not go through encryption process
565575  size_t  i;
566-   for  (i = 0 ; i < count; i++)
576+   for  (i = 0 ; i < count; i++) { 
567577    if  (bufs[i].len  > 0 ) {
568578      empty = false ;
569579      break ;
570580    }
581+   }
582+ 
583+   //  We want to trigger a Write() on the underlying stream to drive the stream
584+   //  system, but don't want to encrypt empty buffers into a TLS frame, so see
585+   //  if we can find something to Write().
586+   //  First, call ClearOut(). It does an SSL_read(), which might cause handshake
587+   //  or other internal messages to be encrypted. If it does, write them later
588+   //  with EncOut().
589+   //  If there is still no encrypted output, call Write(bufs) on the underlying
590+   //  stream. Since the bufs are empty, it won't actually write non-TLS data
591+   //  onto the socket, we just want the side-effects. After, make sure the
592+   //  WriteWrap was accepted by the stream, or that we call Done() on it.
571593  if  (empty) {
572594    ClearOut ();
573-     //  However, if there is any data that should be written to the socket,
574-     //  the callback should not be invoked immediately
575595    if  (BIO_pending (enc_out_) == 0 ) {
576596      CHECK_NULL (current_empty_write_);
577597      current_empty_write_ = w;
@@ -591,7 +611,7 @@ int TLSWrap::DoWrite(WriteWrap* w,
591611  CHECK_NULL (current_write_);
592612  current_write_ = w;
593613
594-   //  Write queued  data
614+   //  Write encrypted  data to underlying stream and call Done(). 
595615  if  (empty) {
596616    EncOut ();
597617    return  0 ;
@@ -610,17 +630,20 @@ int TLSWrap::DoWrite(WriteWrap* w,
610630  if  (i != count) {
611631    int  err;
612632    Local<Value> arg = GetSSLError (written, &err, &error_);
633+ 
634+     //  If we stopped writing because of an error, it's fatal, discard the data.
613635    if  (!arg.IsEmpty ()) {
614636      current_write_ = nullptr ;
615637      return  UV_EPROTO;
616638    }
617639
640+     //  Otherwise, save unwritten data so it can be written later by ClearIn().
618641    pending_cleartext_input_.insert (pending_cleartext_input_.end (),
619642                                    &bufs[i],
620643                                    &bufs[count]);
621644  }
622645
623-   //  Try writing data immediately 
646+   //  Write any encrypted/handshake output that may be ready. 
624647  EncOut ();
625648
626649  return  0 ;
@@ -652,17 +675,20 @@ void TLSWrap::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
652675    return ;
653676  }
654677
655-   //  Only client connections can receive data
656678  if  (ssl_ == nullptr ) {
657679    EmitRead (UV_EPROTO);
658680    return ;
659681  }
660682
661-   //  Commit read data
683+   //  Commit the amount of data actually read into the peeked/allocated buffer
684+   //  from the underlying stream.
662685  crypto::NodeBIO* enc_in = crypto::NodeBIO::FromBIO (enc_in_);
663686  enc_in->Commit (nread);
664687
665-   //  Parse ClientHello first
688+   //  Parse ClientHello first, if we need to. It's only parsed if session event
689+   //  listeners are used on the server side.  "ended" is the initial state, so
690+   //  can mean parsing was never started, or that parsing is finished. Either
691+   //  way, ended means we can give the buffered data to SSL.
666692  if  (!hello_parser_.IsEnded ()) {
667693    size_t  avail = 0 ;
668694    uint8_t * data = reinterpret_cast <uint8_t *>(enc_in->Peek (&avail));
0 commit comments