@@ -291,7 +291,7 @@ void TLSWrap::EncOut() {
291291 // No encrypted output ready to write to the underlying stream.
292292 if (BIO_pending (enc_out_) == 0 ) {
293293 Debug (this , " No pending encrypted output" );
294- if (pending_cleartext_input_.empty () )
294+ if (pending_cleartext_input_.size () == 0 )
295295 InvokeQueued (0 );
296296 return ;
297297 }
@@ -509,28 +509,21 @@ void TLSWrap::ClearIn() {
509509 return ;
510510 }
511511
512- std::vector<uv_buf_t > buffers;
513- buffers.swap (pending_cleartext_input_);
512+ if (pending_cleartext_input_.size () == 0 ) {
513+ Debug (this , " Returning from ClearIn(), no pending data" );
514+ return ;
515+ }
514516
517+ std::vector<char > data = std::move (pending_cleartext_input_);
515518 crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
516519
517- size_t i;
518- int written = 0 ;
519- for (i = 0 ; i < buffers.size (); ++i) {
520- size_t avail = buffers[i].len ;
521- char * data = buffers[i].base ;
522- written = SSL_write (ssl_.get (), data, avail);
523- Debug (this , " Writing %zu bytes, written = %d" , avail, written);
524- CHECK (written == -1 || written == static_cast <int >(avail));
525- if (written == -1 )
526- break ;
527- }
520+ int written = SSL_write (ssl_.get (), data.data (), data.size ());
521+ Debug (this , " Writing %zu bytes, written = %d" , data.size (), written);
522+ CHECK (written == -1 || written == static_cast <int >(data.size ()));
528523
529524 // All written
530- if (i == buffers. size () ) {
525+ if (written != - 1 ) {
531526 Debug (this , " Successfully wrote all data to SSL" );
532- // We wrote all the buffers, so no writes failed (written < 0 on failure).
533- CHECK_GE (written, 0 );
534527 return ;
535528 }
536529
@@ -548,13 +541,10 @@ void TLSWrap::ClearIn() {
548541 // possible.
549542 InvokeQueued (UV_EPROTO, error_str.c_str ());
550543 } else {
551- Debug (this , " Pushing back %zu buffers" , buffers.size () - i);
552- // Push back the not-yet-written pending buffers into their queue.
553- // This can be skipped in the error case because no further writes
554- // would succeed anyway.
555- pending_cleartext_input_.insert (pending_cleartext_input_.end (),
556- buffers.begin () + i,
557- buffers.end ());
544+ Debug (this , " Pushing data back" );
545+ // Push back the not-yet-written data. This can be skipped in the error
546+ // case because no further writes would succeed anyway.
547+ pending_cleartext_input_ = std::move (data);
558548 }
559549
560550 return ;
@@ -640,14 +630,10 @@ int TLSWrap::DoWrite(WriteWrap* w,
640630 return UV_EPROTO;
641631 }
642632
643- bool empty = true ;
633+ size_t length = 0 ;
644634 size_t i;
645- for (i = 0 ; i < count; i++) {
646- if (bufs[i].len > 0 ) {
647- empty = false ;
648- break ;
649- }
650- }
635+ for (i = 0 ; i < count; i++)
636+ length += bufs[i].len ;
651637
652638 // We want to trigger a Write() on the underlying stream to drive the stream
653639 // system, but don't want to encrypt empty buffers into a TLS frame, so see
@@ -659,7 +645,7 @@ int TLSWrap::DoWrite(WriteWrap* w,
659645 // stream. Since the bufs are empty, it won't actually write non-TLS data
660646 // onto the socket, we just want the side-effects. After, make sure the
661647 // WriteWrap was accepted by the stream, or that we call Done() on it.
662- if (empty ) {
648+ if (length == 0 ) {
663649 Debug (this , " Empty write" );
664650 ClearOut ();
665651 if (BIO_pending (enc_out_) == 0 ) {
@@ -683,23 +669,36 @@ int TLSWrap::DoWrite(WriteWrap* w,
683669 current_write_ = w;
684670
685671 // Write encrypted data to underlying stream and call Done().
686- if (empty ) {
672+ if (length == 0 ) {
687673 EncOut ();
688674 return 0 ;
689675 }
690676
677+ std::vector<char > data;
691678 crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
692679
693680 int written = 0 ;
694- for (i = 0 ; i < count; i++) {
695- written = SSL_write (ssl_.get (), bufs[i].base , bufs[i].len );
696- CHECK (written == -1 || written == static_cast <int >(bufs[i].len ));
697- Debug (this , " Writing %zu bytes, written = %d" , bufs[i].len , written);
698- if (written == -1 )
699- break ;
681+ if (count != 1 ) {
682+ data = std::vector<char >(length);
683+ size_t offset = 0 ;
684+ for (i = 0 ; i < count; i++) {
685+ memcpy (data.data () + offset, bufs[i].base , bufs[i].len );
686+ offset += bufs[i].len ;
687+ }
688+ written = SSL_write (ssl_.get (), data.data (), length);
689+ } else {
690+ // Only one buffer: try to write directly, only store if it fails
691+ written = SSL_write (ssl_.get (), bufs[0 ].base , bufs[0 ].len );
692+ if (written == -1 ) {
693+ data = std::vector<char >(length);
694+ memcpy (data.data (), bufs[0 ].base , bufs[0 ].len );
695+ }
700696 }
701697
702- if (i != count) {
698+ CHECK (written == -1 || written == static_cast <int >(length));
699+ Debug (this , " Writing %zu bytes, written = %d" , length, written);
700+
701+ if (written == -1 ) {
703702 int err;
704703 Local<Value> arg = GetSSLError (written, &err, &error_);
705704
@@ -710,11 +709,10 @@ int TLSWrap::DoWrite(WriteWrap* w,
710709 return UV_EPROTO;
711710 }
712711
713- Debug (this , " Saving %zu buffers for later write" , count - i );
712+ Debug (this , " Saving data for later write" );
714713 // Otherwise, save unwritten data so it can be written later by ClearIn().
715- pending_cleartext_input_.insert (pending_cleartext_input_.end (),
716- &bufs[i],
717- &bufs[count]);
714+ CHECK_EQ (pending_cleartext_input_.size (), 0 );
715+ pending_cleartext_input_ = std::move (data);
718716 }
719717
720718 // Write any encrypted/handshake output that may be ready.
0 commit comments