-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Keep track of DTLS packet sizes to prevent partial reads.
The current use of rtc::FifoBuffer can lead to reading across DTLS packet boundaries which could cause packets to not being processed correctly. This CL introduces the new class rtc::BufferQueue and changes the StreamInterfaceChannel to use it instead of the rtc::FifoBuffer. BUG=chromium:447431 R=juberti@google.com Review URL: https://webrtc-codereview.appspot.com/52509004 Cr-Commit-Position: refs/heads/master@{#9254}
- Loading branch information
Showing
8 changed files
with
245 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* Copyright 2015 The WebRTC Project Authors. All rights reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style license | ||
* that can be found in the LICENSE file in the root of the source | ||
* tree. An additional intellectual property rights grant can be found | ||
* in the file PATENTS. All contributing project authors may | ||
* be found in the AUTHORS file in the root of the source tree. | ||
*/ | ||
|
||
#include "webrtc/base/bufferqueue.h" | ||
|
||
namespace rtc { | ||
|
||
BufferQueue::BufferQueue(size_t capacity, size_t default_size) | ||
: capacity_(capacity), default_size_(default_size) { | ||
} | ||
|
||
BufferQueue::~BufferQueue() { | ||
CritScope cs(&crit_); | ||
|
||
for (Buffer* buffer : queue_) { | ||
delete buffer; | ||
} | ||
for (Buffer* buffer : free_list_) { | ||
delete buffer; | ||
} | ||
} | ||
|
||
size_t BufferQueue::size() const { | ||
CritScope cs(&crit_); | ||
return queue_.size(); | ||
} | ||
|
||
bool BufferQueue::ReadFront(void* buffer, size_t bytes, size_t* bytes_read) { | ||
CritScope cs(&crit_); | ||
if (queue_.empty()) { | ||
return false; | ||
} | ||
|
||
Buffer* packet = queue_.front(); | ||
queue_.pop_front(); | ||
|
||
size_t next_packet_size = packet->size(); | ||
if (bytes > next_packet_size) { | ||
bytes = next_packet_size; | ||
} | ||
|
||
memcpy(buffer, packet->data(), bytes); | ||
if (bytes_read) { | ||
*bytes_read = bytes; | ||
} | ||
free_list_.push_back(packet); | ||
return true; | ||
} | ||
|
||
bool BufferQueue::WriteBack(const void* buffer, size_t bytes, | ||
size_t* bytes_written) { | ||
CritScope cs(&crit_); | ||
if (queue_.size() == capacity_) { | ||
return false; | ||
} | ||
|
||
Buffer* packet; | ||
if (!free_list_.empty()) { | ||
packet = free_list_.back(); | ||
free_list_.pop_back(); | ||
} else { | ||
packet = new Buffer(bytes, default_size_); | ||
} | ||
|
||
packet->SetData(static_cast<const uint8_t*>(buffer), bytes); | ||
if (bytes_written) { | ||
*bytes_written = bytes; | ||
} | ||
queue_.push_back(packet); | ||
return true; | ||
} | ||
|
||
} // namespace rtc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright 2015 The WebRTC Project Authors. All rights reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style license | ||
* that can be found in the LICENSE file in the root of the source | ||
* tree. An additional intellectual property rights grant can be found | ||
* in the file PATENTS. All contributing project authors may | ||
* be found in the AUTHORS file in the root of the source tree. | ||
*/ | ||
|
||
#ifndef WEBRTC_BASE_BUFFERQUEUE_H_ | ||
#define WEBRTC_BASE_BUFFERQUEUE_H_ | ||
|
||
#include <deque> | ||
#include <vector> | ||
|
||
#include "webrtc/base/buffer.h" | ||
#include "webrtc/base/criticalsection.h" | ||
|
||
namespace rtc { | ||
|
||
class BufferQueue { | ||
public: | ||
// Creates a buffer queue queue with a given capacity and default buffer size. | ||
BufferQueue(size_t capacity, size_t default_size); | ||
~BufferQueue(); | ||
|
||
// Return number of queued buffers. | ||
size_t size() const; | ||
|
||
// ReadFront will only read one buffer at a time and will truncate buffers | ||
// that don't fit in the passed memory. | ||
bool ReadFront(void* data, size_t bytes, size_t* bytes_read); | ||
|
||
// WriteBack always writes either the complete memory or nothing. | ||
bool WriteBack(const void* data, size_t bytes, size_t* bytes_written); | ||
|
||
private: | ||
size_t capacity_; | ||
size_t default_size_; | ||
std::deque<Buffer*> queue_; | ||
std::vector<Buffer*> free_list_; | ||
mutable CriticalSection crit_; // object lock | ||
|
||
DISALLOW_COPY_AND_ASSIGN(BufferQueue); | ||
}; | ||
|
||
} // namespace rtc | ||
|
||
#endif // WEBRTC_BASE_BUFFERQUEUE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright 2015 The WebRTC Project Authors. All rights reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style license | ||
* that can be found in the LICENSE file in the root of the source | ||
* tree. An additional intellectual property rights grant can be found | ||
* in the file PATENTS. All contributing project authors may | ||
* be found in the AUTHORS file in the root of the source tree. | ||
*/ | ||
|
||
#include "webrtc/base/bufferqueue.h" | ||
#include "webrtc/base/gunit.h" | ||
|
||
namespace rtc { | ||
|
||
TEST(BufferQueueTest, TestAll) { | ||
const size_t kSize = 16; | ||
const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; | ||
char out[kSize * 2]; | ||
size_t bytes; | ||
BufferQueue queue1(1, kSize); | ||
BufferQueue queue2(2, kSize); | ||
|
||
// The queue is initially empty. | ||
EXPECT_EQ(0u, queue1.size()); | ||
EXPECT_FALSE(queue1.ReadFront(out, kSize, &bytes)); | ||
|
||
// A write should succeed. | ||
EXPECT_TRUE(queue1.WriteBack(in, kSize, &bytes)); | ||
EXPECT_EQ(kSize, bytes); | ||
EXPECT_EQ(1u, queue1.size()); | ||
|
||
// The queue is full now (only one buffer allowed). | ||
EXPECT_FALSE(queue1.WriteBack(in, kSize, &bytes)); | ||
EXPECT_EQ(1u, queue1.size()); | ||
|
||
// Reading previously written buffer. | ||
EXPECT_TRUE(queue1.ReadFront(out, kSize, &bytes)); | ||
EXPECT_EQ(kSize, bytes); | ||
EXPECT_EQ(0, memcmp(in, out, kSize)); | ||
|
||
// The queue is empty again now. | ||
EXPECT_FALSE(queue1.ReadFront(out, kSize, &bytes)); | ||
EXPECT_EQ(0u, queue1.size()); | ||
|
||
// Reading only returns available data. | ||
EXPECT_TRUE(queue1.WriteBack(in, kSize, &bytes)); | ||
EXPECT_EQ(kSize, bytes); | ||
EXPECT_EQ(1u, queue1.size()); | ||
EXPECT_TRUE(queue1.ReadFront(out, kSize * 2, &bytes)); | ||
EXPECT_EQ(kSize, bytes); | ||
EXPECT_EQ(0, memcmp(in, out, kSize)); | ||
EXPECT_EQ(0u, queue1.size()); | ||
|
||
// Reading maintains buffer boundaries. | ||
EXPECT_TRUE(queue2.WriteBack(in, kSize / 2, &bytes)); | ||
EXPECT_EQ(1u, queue2.size()); | ||
EXPECT_TRUE(queue2.WriteBack(in + kSize / 2, kSize / 2, &bytes)); | ||
EXPECT_EQ(2u, queue2.size()); | ||
EXPECT_TRUE(queue2.ReadFront(out, kSize, &bytes)); | ||
EXPECT_EQ(kSize / 2, bytes); | ||
EXPECT_EQ(0, memcmp(in, out, kSize / 2)); | ||
EXPECT_EQ(1u, queue2.size()); | ||
EXPECT_TRUE(queue2.ReadFront(out, kSize, &bytes)); | ||
EXPECT_EQ(kSize / 2, bytes); | ||
EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 2)); | ||
EXPECT_EQ(0u, queue2.size()); | ||
|
||
// Reading truncates buffers. | ||
EXPECT_TRUE(queue2.WriteBack(in, kSize / 2, &bytes)); | ||
EXPECT_EQ(1u, queue2.size()); | ||
EXPECT_TRUE(queue2.WriteBack(in + kSize / 2, kSize / 2, &bytes)); | ||
EXPECT_EQ(2u, queue2.size()); | ||
// Read first packet partially in too-small buffer. | ||
EXPECT_TRUE(queue2.ReadFront(out, kSize / 4, &bytes)); | ||
EXPECT_EQ(kSize / 4, bytes); | ||
EXPECT_EQ(0, memcmp(in, out, kSize / 4)); | ||
EXPECT_EQ(1u, queue2.size()); | ||
// Remainder of first packet is truncated, reading starts with next packet. | ||
EXPECT_TRUE(queue2.ReadFront(out, kSize, &bytes)); | ||
EXPECT_EQ(kSize / 2, bytes); | ||
EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 2)); | ||
EXPECT_EQ(0u, queue2.size()); | ||
} | ||
|
||
} // namespace rtc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters