Skip to content

Commit 014ab77

Browse files
committed
crypto: try moving read head in Peek()
Otherwise it might get stall (`Peek()` will return zero-length chunk) in following situation: 1. `Write(kBufferLength)` 2. `Read(kBufferLength)` 3. `Write(anything)` 4. `Peek()` => `len=0`
1 parent ea8fece commit 014ab77

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

src/node_crypto_bio.cc

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,25 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, void* ptr) {
191191
}
192192

193193

194+
void NodeBIO::TryMoveReadHead() {
195+
// `read_pos_` and `write_pos_` means the position of the reader and writer
196+
// inside the buffer, respectively. When they're equal - its safe to reset
197+
// them, because both reader and writer will continue doing their stuff
198+
// from new (zero) positions.
199+
if (read_head_->read_pos_ != read_head_->write_pos_)
200+
return;
201+
202+
// Reset positions
203+
read_head_->read_pos_ = 0;
204+
read_head_->write_pos_ = 0;
205+
206+
// Move read_head_ forward, just in case if there're still some data to
207+
// read in the next buffer.
208+
if (read_head_ != write_head_)
209+
read_head_ = read_head_->next_;
210+
}
211+
212+
194213
size_t NodeBIO::Read(char* out, size_t size) {
195214
size_t bytes_read = 0;
196215
size_t expected = Length() > size ? size : Length();
@@ -213,16 +232,7 @@ size_t NodeBIO::Read(char* out, size_t size) {
213232
offset += avail;
214233
left -= avail;
215234

216-
// Move to next buffer
217-
if (read_head_->read_pos_ == read_head_->write_pos_) {
218-
read_head_->read_pos_ = 0;
219-
read_head_->write_pos_ = 0;
220-
221-
// But not get beyond write_head_
222-
if (length_ != bytes_read && read_head_ != write_head_) {
223-
read_head_ = read_head_->next_;
224-
}
225-
}
235+
TryMoveReadHead();
226236
}
227237
assert(expected == bytes_read);
228238
length_ -= bytes_read;
@@ -331,6 +341,10 @@ void NodeBIO::Write(const char* data, size_t size) {
331341
assert(write_head_->write_pos_ == kBufferLength);
332342
TryAllocateForWrite();
333343
write_head_ = write_head_->next_;
344+
345+
// Additionally, since we're moved to the next buffer, read head
346+
// may be moved as well.
347+
TryMoveReadHead();
334348
}
335349
}
336350
assert(left == 0);

src/node_crypto_bio.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class NodeBIO {
3838

3939
static BIO* New();
4040

41+
// Move read head to next buffer if needed
42+
void TryMoveReadHead();
43+
4144
// Allocate new buffer for write if needed
4245
void TryAllocateForWrite();
4346

0 commit comments

Comments
 (0)