forked from envoyproxy/envoy
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
listener: remove the peek from the listener filters (envoyproxy#17395)
Signed-off-by: He Jie Xu <hejie.xu@intel.com>
- Loading branch information
1 parent
f6664dd
commit 3d35a28
Showing
56 changed files
with
2,211 additions
and
1,215 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
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,33 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#include "envoy/buffer/buffer.h" | ||
#include "envoy/common/pure.h" | ||
|
||
namespace Envoy { | ||
namespace Network { | ||
|
||
/** | ||
* Interface for ListenerFilterBuffer | ||
*/ | ||
class ListenerFilterBuffer { | ||
public: | ||
virtual ~ListenerFilterBuffer() = default; | ||
|
||
/** | ||
* Return a single const raw slice to the buffer of the data. | ||
* @return a Buffer::ConstRawSlice pointed to raw buffer. | ||
*/ | ||
virtual const Buffer::ConstRawSlice rawSlice() const PURE; | ||
|
||
/** | ||
* Drain the data from the beginning of the buffer. | ||
* @param length the length of data to drain. | ||
* @return a bool indicate the drain is successful or not. | ||
*/ | ||
virtual bool drain(uint64_t length) PURE; | ||
}; | ||
|
||
} // namespace Network | ||
} // namespace Envoy |
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,107 @@ | ||
#include "source/common/network/listener_filter_buffer_impl.h" | ||
|
||
#include <string> | ||
|
||
namespace Envoy { | ||
namespace Network { | ||
|
||
ListenerFilterBufferImpl::ListenerFilterBufferImpl(IoHandle& io_handle, | ||
Event::Dispatcher& dispatcher, | ||
ListenerFilterBufferOnCloseCb close_cb, | ||
ListenerFilterBufferOnDataCb on_data_cb, | ||
uint64_t buffer_size) | ||
: io_handle_(io_handle), dispatcher_(dispatcher), on_close_cb_(close_cb), | ||
on_data_cb_(on_data_cb), buffer_(std::make_unique<uint8_t[]>(buffer_size)), | ||
base_(buffer_.get()), buffer_size_(buffer_size) { | ||
// If the buffer_size not greater than 0, it means that doesn't expect any data. | ||
ASSERT(buffer_size > 0); | ||
|
||
io_handle_.initializeFileEvent( | ||
dispatcher_, [this](uint32_t events) { onFileEvent(events); }, | ||
Event::PlatformDefaultTriggerType, Event::FileReadyType::Read); | ||
} | ||
|
||
const Buffer::ConstRawSlice ListenerFilterBufferImpl::rawSlice() const { | ||
Buffer::ConstRawSlice slice; | ||
slice.mem_ = base_; | ||
slice.len_ = data_size_; | ||
return slice; | ||
} | ||
|
||
bool ListenerFilterBufferImpl::drain(uint64_t length) { | ||
if (length == 0) { | ||
return true; | ||
} | ||
|
||
ASSERT(length <= data_size_); | ||
|
||
uint64_t read_size = 0; | ||
while (read_size < length) { | ||
auto result = io_handle_.recv(base_, length - read_size, 0); | ||
ENVOY_LOG(trace, "recv returned: {}", result.return_value_); | ||
|
||
if (!result.ok()) { | ||
// `IoErrorCode::Again` isn't processed here, since | ||
// the data already in the socket buffer. | ||
return false; | ||
} | ||
read_size += result.return_value_; | ||
} | ||
base_ += length; | ||
data_size_ -= length; | ||
return true; | ||
} | ||
|
||
PeekState ListenerFilterBufferImpl::peekFromSocket() { | ||
// Reset buffer base in case of draining changed base. | ||
auto old_base = base_; | ||
base_ = buffer_.get(); | ||
const auto result = io_handle_.recv(base_, buffer_size_, MSG_PEEK); | ||
ENVOY_LOG(trace, "recv returned: {}", result.return_value_); | ||
|
||
if (!result.ok()) { | ||
if (result.err_->getErrorCode() == Api::IoError::IoErrorCode::Again) { | ||
ENVOY_LOG(trace, "recv return try again"); | ||
base_ = old_base; | ||
return PeekState::Again; | ||
} | ||
ENVOY_LOG(debug, "recv failed: {}: {}", static_cast<int>(result.err_->getErrorCode()), | ||
result.err_->getErrorDetails()); | ||
return PeekState::Error; | ||
} | ||
// Remote closed | ||
if (result.return_value_ == 0) { | ||
ENVOY_LOG(debug, "recv failed: remote closed"); | ||
return PeekState::RemoteClose; | ||
} | ||
data_size_ = result.return_value_; | ||
ASSERT(data_size_ <= buffer_size_); | ||
|
||
return PeekState::Done; | ||
} | ||
|
||
void ListenerFilterBufferImpl::resetCapacity(uint64_t size) { | ||
buffer_ = std::make_unique<uint8_t[]>(size); | ||
base_ = buffer_.get(); | ||
buffer_size_ = size; | ||
data_size_ = 0; | ||
} | ||
|
||
void ListenerFilterBufferImpl::activateFileEvent(uint32_t events) { onFileEvent(events); } | ||
|
||
void ListenerFilterBufferImpl::onFileEvent(uint32_t events) { | ||
ENVOY_LOG(trace, "onFileEvent: {}", events); | ||
|
||
auto state = peekFromSocket(); | ||
if (state == PeekState::Done) { | ||
on_data_cb_(*this); | ||
} else if (state == PeekState::Error) { | ||
on_close_cb_(true); | ||
} else if (state == PeekState::RemoteClose) { | ||
on_close_cb_(false); | ||
} | ||
// Did nothing for `Api::IoError::IoErrorCode::Again` | ||
} | ||
|
||
} // namespace Network | ||
} // namespace Envoy |
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,72 @@ | ||
#pragma once | ||
|
||
#include <functional> | ||
#include <memory> | ||
|
||
#include "envoy/buffer/buffer.h" | ||
#include "envoy/network/io_handle.h" | ||
#include "envoy/network/listener_filter_buffer.h" | ||
|
||
#include "source/common/buffer/buffer_impl.h" | ||
|
||
namespace Envoy { | ||
namespace Network { | ||
|
||
class ListenerFilterBufferImpl; | ||
using ListenerFilterBufferOnCloseCb = std::function<void(bool)>; | ||
using ListenerFilterBufferOnDataCb = std::function<void(ListenerFilterBufferImpl&)>; | ||
|
||
enum class PeekState { | ||
// Peek data status successful. | ||
Done, | ||
// Need to try again. | ||
Again, | ||
// Error to peek data. | ||
Error, | ||
// Connection closed by remote. | ||
RemoteClose, | ||
}; | ||
|
||
class ListenerFilterBufferImpl : public ListenerFilterBuffer, Logger::Loggable<Logger::Id::filter> { | ||
public: | ||
ListenerFilterBufferImpl(IoHandle& io_handle, Event::Dispatcher& dispatcher, | ||
ListenerFilterBufferOnCloseCb close_cb, | ||
ListenerFilterBufferOnDataCb on_data_cb, uint64_t buffer_size); | ||
|
||
// ListenerFilterBuffer | ||
const Buffer::ConstRawSlice rawSlice() const override; | ||
bool drain(uint64_t length) override; | ||
|
||
/** | ||
* Trigger the data peek from the socket. | ||
*/ | ||
PeekState peekFromSocket(); | ||
|
||
void reset() { io_handle_.resetFileEvents(); } | ||
|
||
void activateFileEvent(uint32_t events); | ||
uint64_t capacity() const { return buffer_size_; } | ||
void resetCapacity(uint64_t size); | ||
|
||
private: | ||
void onFileEvent(uint32_t events); | ||
|
||
IoHandle& io_handle_; | ||
Event::Dispatcher& dispatcher_; | ||
ListenerFilterBufferOnCloseCb on_close_cb_; | ||
ListenerFilterBufferOnDataCb on_data_cb_; | ||
|
||
// The buffer for the data peeked from the socket. | ||
std::unique_ptr<uint8_t[]> buffer_; | ||
// The start of buffer. | ||
uint8_t* base_; | ||
// The size of buffer; | ||
uint64_t buffer_size_; | ||
// The size of valid data. | ||
uint64_t data_size_{0}; | ||
}; | ||
|
||
using ListenerFilterBufferImplPtr = std::unique_ptr<ListenerFilterBufferImpl>; | ||
|
||
} // namespace Network | ||
} // namespace Envoy |
Oops, something went wrong.