-
Notifications
You must be signed in to change notification settings - Fork 5.5k
listener: remove the peek from the listener filters #17395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 129 commits
8be8d06
dfe1577
c803b2c
a78ca39
8aaacff
f47023a
6ceb43b
1fc908d
7c27f7f
ab3fb54
066a931
0ce5112
375c1a5
eb61a46
7523574
31889ef
78d3104
52a5752
7ba4fb9
e8faf52
8a4d00e
bdf5559
133a795
2d1eda8
9696e49
0f4e465
f9ac956
4ce02f6
dff726a
94104e2
e227e38
efa5857
a07c7f9
d558321
e8ce277
3f73e69
7b8d032
82e5d2b
ae391ec
789456e
065d6b5
c2a57ad
d2540e8
bbfca55
1d55e8d
a360a31
06aa973
aba84f9
9015048
df2ad02
aaa6d9a
7bffad3
37c16a5
c7858e3
80f8f8b
9725f08
6b0f734
62c3845
0fff99b
4bda3ac
3be4ee0
d88ae5a
4a8d69e
41b3aa0
a606cf4
705a58d
fa5a289
c2b5b44
fd85009
8972610
4aeaeae
544a1c8
15fc820
4e60815
fe11b35
5370061
775f040
052fdca
268b047
1534dcd
347d474
6efde49
e98e7b9
0e26bd2
3f428ef
002aa00
bd75c8e
3eb8880
f2fd1fb
72e8f20
db35fbf
16caa4f
a479ef8
d3dd4d3
23c6341
1c1223f
abe8be2
046a769
02e5397
5705fe5
3b60d73
bfb1336
31aee37
55361a3
320e370
f73213d
a2e8799
d113f4c
0c03750
52828ee
959170b
d023827
d2fe6e2
d673110
6a25bfd
f5491ce
eee4e6e
7df678c
7e7c3da
b3d9a42
dfc5527
7dcd41c
bef9023
48b574d
72d978a
d32a126
0749507
12cb6b3
2ded76a
e77307a
cec8291
c9a90af
7965de9
197af3b
dbcbc21
607e348
f94ff76
a7baa39
03b494e
1c5a548
6df4baa
ff70529
0250b08
1b734b1
e1d277c
aa0e113
c713a4f
0296e09
0c5f498
f9d520f
a3cd1e0
0c9d84d
4088880
8d190cb
ec80e88
7daa3f0
1abda9f
8b454fd
c534a97
3248c72
3ea4755
920dc64
ca4fb1b
af40bae
38dffc7
b8bb4df
5136c59
cab9e59
730cf45
2b5636d
d30d7fc
ca84c78
2604a1b
b523971
5cdfe2b
26f32f0
ea26901
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| #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 return True if the drain success, otherwise return False. | ||
| */ | ||
| virtual bool drain(uint64_t length) PURE; | ||
|
|
||
| /** | ||
| * Return the length of data in the buffer | ||
| * @return length The length of data in the buffer. | ||
| */ | ||
| virtual uint64_t length() const PURE; | ||
|
soulxu marked this conversation as resolved.
Outdated
|
||
| }; | ||
|
|
||
| } // namespace Network | ||
| } // namespace Envoy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| #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 (1) { | ||
|
soulxu marked this conversation as resolved.
Outdated
|
||
| auto result = io_handle_.recv(base_, length - read_size, 0); | ||
| ENVOY_LOG(trace, "recv returned: {}", result.return_value_); | ||
|
|
||
| // The socket buffer is expected to have the data. so the | ||
| // recv doesn't expected to fail. | ||
| ASSERT(result.ok()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are there any error conditions on a socket (client sends RST maybe? Some administrative operation on the host?) that could make the operation fail? It may be safer to break out of the loop if this fails, even though it would be unexpected, so avoid an infinite loop.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree that it is safer to break out of the loop. Do we want to throw an exception here? or we want to close the connection? sounds like second on is better.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Close the connection. Exceptions are only allowed while handling configuration. |
||
|
|
||
| read_size += result.return_value_; | ||
| if (read_size < length) { | ||
| continue; | ||
| } | ||
| base_ += length; | ||
| data_size_ -= length; | ||
| buffer_size_ -= length; | ||
| break; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| PeekState ListenerFilterBufferImpl::peekFromSocket() { | ||
| const auto result = io_handle_.recv(base_, buffer_size_, MSG_PEEK); | ||
|
mattklein123 marked this conversation as resolved.
|
||
| 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"); | ||
| return PeekState::Again; | ||
| } | ||
| ENVOY_LOG(debug, "recv failed: {}: {}", 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::Error; | ||
| } | ||
| data_size_ = result.return_value_; | ||
| ASSERT(data_size_ <= buffer_size_); | ||
|
|
||
| return PeekState::Done; | ||
| } | ||
|
|
||
| void ListenerFilterBufferImpl::onFileEvent(uint32_t events) { | ||
| ENVOY_LOG(trace, "onFileEvent: {}", events); | ||
|
|
||
| auto state = peekFromSocket(); | ||
| if (state == PeekState::Done) { | ||
| on_data_cb_(); | ||
| } else if (state == PeekState::Error) { | ||
| on_close_cb_(); | ||
| } | ||
| // Did nothing for `Api::IoError::IoErrorCode::Again` | ||
| } | ||
|
|
||
| } // namespace Network | ||
| } // namespace Envoy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #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 { | ||
|
|
||
| using ListenerFilterBufferOnCloseCb = std::function<void()>; | ||
| using ListenerFilterBufferOnDataCb = std::function<void()>; | ||
|
|
||
| enum class PeekState { | ||
| // Peek data status successful. | ||
| Done, | ||
| // Need to try again. | ||
| Again, | ||
| // Error to peek data. | ||
| Error | ||
| }; | ||
|
|
||
| class ListenerFilterBufferImpl : public ListenerFilterBuffer, Logger::Loggable<Logger::Id::filter> { | ||
| public: | ||
| ListenerFilterBufferImpl(IoHandle& io_handle, Event::Dispatcher& dispatcher, | ||
|
soulxu marked this conversation as resolved.
|
||
| ListenerFilterBufferOnCloseCb close_cb, | ||
| ListenerFilterBufferOnDataCb on_data_cb, uint64_t buffer_size); | ||
|
|
||
| // ListenerFilterBuffer | ||
|
soulxu marked this conversation as resolved.
|
||
| const Buffer::ConstRawSlice rawSlice() const override; | ||
|
soulxu marked this conversation as resolved.
|
||
| // ListenerFilterBuffer | ||
| bool drain(uint64_t length) override; | ||
| // ListenerFilterBuffer | ||
| uint64_t length() const override { return data_size_; } | ||
|
|
||
| /** | ||
| * Trigger the data peek from the socket. | ||
| */ | ||
| PeekState peekFromSocket(); | ||
|
|
||
| void reset() { io_handle_.resetFileEvents(); } | ||
|
|
||
| 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}; | ||
|
soulxu marked this conversation as resolved.
|
||
| }; | ||
|
|
||
| using ListenerFilterBufferImplPtr = std::unique_ptr<ListenerFilterBufferImpl>; | ||
|
|
||
| } // namespace Network | ||
| } // namespace Envoy | ||
Uh oh!
There was an error while loading. Please reload this page.