@@ -291,7 +291,7 @@ void TLSWrap::EncOut() {
291
291
// No encrypted output ready to write to the underlying stream.
292
292
if (BIO_pending (enc_out_) == 0 ) {
293
293
Debug (this , " No pending encrypted output" );
294
- if (pending_cleartext_input_.empty () )
294
+ if (pending_cleartext_input_.size () == 0 )
295
295
InvokeQueued (0 );
296
296
return ;
297
297
}
@@ -509,28 +509,21 @@ void TLSWrap::ClearIn() {
509
509
return ;
510
510
}
511
511
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
+ }
514
516
517
+ std::vector<char > data = std::move (pending_cleartext_input_);
515
518
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
516
519
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 ()));
528
523
529
524
// All written
530
- if (i == buffers. size () ) {
525
+ if (written != - 1 ) {
531
526
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 );
534
527
return ;
535
528
}
536
529
@@ -548,13 +541,10 @@ void TLSWrap::ClearIn() {
548
541
// possible.
549
542
InvokeQueued (UV_EPROTO, error_str.c_str ());
550
543
} 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);
558
548
}
559
549
560
550
return ;
@@ -640,14 +630,10 @@ int TLSWrap::DoWrite(WriteWrap* w,
640
630
return UV_EPROTO;
641
631
}
642
632
643
- bool empty = true ;
633
+ size_t length = 0 ;
644
634
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 ;
651
637
652
638
// We want to trigger a Write() on the underlying stream to drive the stream
653
639
// system, but don't want to encrypt empty buffers into a TLS frame, so see
@@ -659,7 +645,7 @@ int TLSWrap::DoWrite(WriteWrap* w,
659
645
// stream. Since the bufs are empty, it won't actually write non-TLS data
660
646
// onto the socket, we just want the side-effects. After, make sure the
661
647
// WriteWrap was accepted by the stream, or that we call Done() on it.
662
- if (empty ) {
648
+ if (length == 0 ) {
663
649
Debug (this , " Empty write" );
664
650
ClearOut ();
665
651
if (BIO_pending (enc_out_) == 0 ) {
@@ -683,23 +669,36 @@ int TLSWrap::DoWrite(WriteWrap* w,
683
669
current_write_ = w;
684
670
685
671
// Write encrypted data to underlying stream and call Done().
686
- if (empty ) {
672
+ if (length == 0 ) {
687
673
EncOut ();
688
674
return 0 ;
689
675
}
690
676
677
+ std::vector<char > data;
691
678
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
692
679
693
680
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
+ }
700
696
}
701
697
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 ) {
703
702
int err;
704
703
Local<Value> arg = GetSSLError (written, &err, &error_);
705
704
@@ -710,11 +709,10 @@ int TLSWrap::DoWrite(WriteWrap* w,
710
709
return UV_EPROTO;
711
710
}
712
711
713
- Debug (this , " Saving %zu buffers for later write" , count - i );
712
+ Debug (this , " Saving data for later write" );
714
713
// 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);
718
716
}
719
717
720
718
// Write any encrypted/handshake output that may be ready.
0 commit comments