-
Notifications
You must be signed in to change notification settings - Fork 5.5k
connection: Add TCP_FASTOPEN listener option #2793
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 11 commits
87bb932
cdfeb38
982a27b
7cc3768
8dcf11d
6f55c84
dea8e2c
cc211dd
d9ba97a
e56a8d7
f2db864
9f3c97e
d2d4a27
a03533a
89a3b99
8289daa
e7ff081
8f40b58
42ad7e4
f90b61f
1d5734a
9e57d17
5abe337
2b21dd5
8626895
521faad
cb298fb
4219d2e
2f47e3d
b9312fd
06d426e
f9f608a
2ca16c3
470f934
e0dbd9f
3dd9372
3f11ee6
ec0fa87
4494d2c
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 |
|---|---|---|
|
|
@@ -31,7 +31,7 @@ class Socket { | |
| */ | ||
| virtual void close() PURE; | ||
|
|
||
| enum class SocketState { PreBind, PostBind }; | ||
| enum class SocketState { PreBind, PostBind, Listening }; | ||
|
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. I think at this point we need clear comments on each of these to explain when they happen in the socket lifetime and relative to each other. Not sure why we need a
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. Agreed. I'll put this in the comments, but the reason for the new state is that on macOS, you cannot set this option until after listen() has been called. PostBind is run between bind() and listen(). Can you think of a better name for PostBind, now that this 3rd state is added? Or just comment it heavily and keep the name?
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. I think it's fine to just comment. As long as there is a clear order in the comments wrt the socket creation -> accept life cycle it's all good.
Contributor
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. SocketState is documented |
||
|
|
||
| /** | ||
| * Visitor class for setting socket options. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,14 +10,16 @@ namespace Envoy { | |
| namespace Network { | ||
|
|
||
| bool SocketOptionImpl::setOption(Socket& socket, Socket::SocketState state) const { | ||
| if (transparent_.has_value()) { | ||
| const int should_transparent = transparent_.value() ? 1 : 0; | ||
| const int error = | ||
| setIpSocketOption(socket, ENVOY_SOCKET_IP_TRANSPARENT, ENVOY_SOCKET_IPV6_TRANSPARENT, | ||
| &should_transparent, sizeof(should_transparent)); | ||
| if (error != 0) { | ||
| ENVOY_LOG(warn, "Setting IP_TRANSPARENT on listener socket failed: {}", strerror(error)); | ||
| return false; | ||
| if (state == Socket::SocketState::PreBind || state == Socket::SocketState::PostBind) { | ||
| if (transparent_.has_value()) { | ||
| const int should_transparent = transparent_.value() ? 1 : 0; | ||
| const int error = | ||
| setIpSocketOption(socket, ENVOY_SOCKET_IP_TRANSPARENT, ENVOY_SOCKET_IPV6_TRANSPARENT, | ||
| &should_transparent, sizeof(should_transparent)); | ||
| if (error != 0) { | ||
| ENVOY_LOG(warn, "Setting IP_TRANSPARENT on listener socket failed: {}", strerror(error)); | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -34,6 +36,26 @@ bool SocketOptionImpl::setOption(Socket& socket, Socket::SocketState state) cons | |
| } | ||
| } | ||
|
|
||
| if (state == Socket::SocketState::Listening) { | ||
|
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. I think this should live in
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. Agreed
Contributor
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. ListenerSocketOption is addressed |
||
| if (tcp_fast_open_queue_length_.has_value()) { | ||
| const int tfo_value = tcp_fast_open_queue_length_.value(); | ||
| const SocketOptionName option_name = ENVOY_SOCKET_TCP_FASTOPEN; | ||
| if (option_name) { | ||
| const int error = Api::OsSysCallsSingleton::get().setsockopt( | ||
|
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. You should provide a TCP equivalent of https://github.com/envoyproxy/envoy/blob/master/source/common/network/socket_option_impl.h#L69.
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. The IP options are more complicated because we have to deal with different options, only sometimes, between ipv4 and ipv6. AFAIK that isn't a thing with tcp socket options, and there's currently only 1 of them. Still think we should add a function for it at this time?
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. I'd suggest to still do this, since we factor out the "Unsupported socket option .." detection and logging code. I think there's a bug in the code here as is; if the socket option is not supported, in this PR it just logs and returns true. It should log and return false (due to the ENOTSUP, which we would generate in the suggested
Contributor
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. I still have to do this.. |
||
| socket.fd(), IPPROTO_TCP, option_name.value(), | ||
| reinterpret_cast<const void*>(&tfo_value), sizeof(tfo_value)); | ||
| if (error != 0) { | ||
| ENVOY_LOG(warn, "Setting TCP_FASTOPEN on listener socket failed: {}", strerror(errno)); | ||
| return false; | ||
| } else { | ||
| ENVOY_LOG(debug, "Successfully set socket option TCP_FASTOPEN to {}", tfo_value); | ||
| } | ||
| } else { | ||
| ENVOY_LOG(warn, "Unsupported socket option TCP_FASTOPEN"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
|
|
||
| #include <netinet/in.h> | ||
| #include <netinet/ip.h> | ||
| #include <netinet/tcp.h> | ||
| #include <sys/socket.h> | ||
|
|
||
| #include "envoy/network/listen_socket.h" | ||
|
|
@@ -41,10 +42,18 @@ typedef absl::optional<int> SocketOptionName; | |
| #define ENVOY_SOCKET_IPV6_FREEBIND Network::SocketOptionName() | ||
| #endif | ||
|
|
||
| #ifdef TCP_FASTOPEN | ||
| #define ENVOY_SOCKET_TCP_FASTOPEN Network::SocketOptionName(TCP_FASTOPEN) | ||
| #else | ||
| #define ENVOY_SOCKET_TCP_FASTOPEN Network::SocketOptionName() | ||
|
Contributor
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. @htuch Do you mean just enforce TCP_FASTOPEN on all listeners by default and then run the tests? |
||
| #endif | ||
|
|
||
| class SocketOptionImpl : public Socket::Option, Logger::Loggable<Logger::Id::connection> { | ||
| public: | ||
| SocketOptionImpl(absl::optional<bool> transparent, absl::optional<bool> freebind) | ||
| : transparent_(transparent), freebind_(freebind) {} | ||
| SocketOptionImpl(absl::optional<bool> transparent, absl::optional<bool> freebind, | ||
| absl::optional<uint32_t> tcp_fast_open_queue_length) | ||
| : transparent_(transparent), freebind_(freebind), | ||
| tcp_fast_open_queue_length_(tcp_fast_open_queue_length) {} | ||
|
|
||
| // Socket::Option | ||
| bool setOption(Socket& socket, Socket::SocketState state) const override; | ||
|
|
@@ -72,6 +81,7 @@ class SocketOptionImpl : public Socket::Option, Logger::Loggable<Logger::Id::con | |
| private: | ||
| const absl::optional<bool> transparent_; | ||
| const absl::optional<bool> freebind_; | ||
| const absl::optional<uint32_t> tcp_fast_open_queue_length_; | ||
| }; | ||
|
|
||
| } // namespace Network | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,7 +114,9 @@ class ListenerSocketOption : public Network::SocketOptionImpl { | |
| ListenerSocketOption(const envoy::api::v2::Listener& config) | ||
| : Network::SocketOptionImpl( | ||
| PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, transparent, absl::optional<bool>{}), | ||
| PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, freebind, absl::optional<bool>{})) {} | ||
| PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, freebind, absl::optional<bool>{}), | ||
| PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, tcp_fast_open_queue_length, | ||
| absl::optional<uint32_t>{})) {} | ||
| }; | ||
|
|
||
| ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManagerImpl& parent, | ||
|
|
@@ -302,6 +304,10 @@ void ListenerImpl::setSocket(const Network::SocketSharedPtr& socket) { | |
| } else { | ||
| ENVOY_LOG(debug, "{}", message); | ||
| } | ||
|
|
||
| // Add the options to the socket_ so that SocketState::Listening options can be | ||
| // set in the worker after listen()/evconnlistener_new() is called. | ||
| socket_->addOption(option); | ||
|
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. Does adding these options here break anything else? |
||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ | |
| #include "gmock/gmock.h" | ||
| #include "gtest/gtest.h" | ||
|
|
||
| using testing::AtLeast; | ||
| using testing::Invoke; | ||
| using testing::Return; | ||
| using testing::_; | ||
|
|
@@ -86,6 +87,35 @@ INSTANTIATE_TEST_CASE_P(IpVersions, ListenerImplTest, | |
| testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), | ||
| TestUtility::ipTestParamsToString); | ||
|
|
||
| // Test that socket options are set after the listener is setup. | ||
| TEST_P(ListenerImplTest, SetListeningSocketOptionsSuccess) { | ||
| Event::DispatcherImpl dispatcher; | ||
| Network::MockListenerCallbacks listener_callbacks; | ||
| Network::MockConnectionHandler connection_handler; | ||
|
|
||
| Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version_), nullptr, | ||
| true); | ||
| std::shared_ptr<MockSocketOption> option = std::make_shared<MockSocketOption>(); | ||
| socket.addOption(option); | ||
| EXPECT_CALL(*option, setOption(_, Socket::SocketState::Listening)).WillOnce(Return(true)); | ||
| TestListenerImpl listener(dispatcher, socket, listener_callbacks, true, false); | ||
| } | ||
|
|
||
| // Test that an exception is thrown if there is an error setting socket options. | ||
| TEST_P(ListenerImplTest, SetListeningSocketOptionsError) { | ||
| Event::DispatcherImpl dispatcher; | ||
| Network::MockListenerCallbacks listener_callbacks; | ||
| Network::MockConnectionHandler connection_handler; | ||
|
|
||
| Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version_), nullptr, | ||
| true); | ||
| std::shared_ptr<MockSocketOption> option = std::make_shared<MockSocketOption>(); | ||
| socket.addOption(option); | ||
| EXPECT_CALL(*option, setOption(_, Socket::SocketState::Listening)).WillOnce(Return(false)); | ||
| EXPECT_THROW(TestListenerImpl(dispatcher, socket, listener_callbacks, true, false), | ||
|
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. Could make this
Contributor
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. Yes, I'm working on this one. |
||
| CreateListenerException); | ||
| } | ||
|
|
||
| TEST_P(ListenerImplTest, UseActualDst) { | ||
| Stats::IsolatedStoreImpl stats_store; | ||
| Event::DispatcherImpl dispatcher; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,42 @@ class SocketOptionImplTest : public testing::Test { | |
| NiceMock<MockListenSocket> socket_; | ||
| Api::MockOsSysCalls os_sys_calls_; | ||
| TestThreadsafeSingletonInjector<Api::OsSysCallsImpl> os_calls{&os_sys_calls_}; | ||
|
|
||
| void testSetSocketOptionSuccess(SocketOptionImpl& socket_option, int socket_level, | ||
| Network::SocketOptionName option_name, int option_val, | ||
| const std::set<Socket::SocketState>& when) { | ||
| Address::Ipv4Instance address("1.2.3.4", 5678); | ||
| const int fd = address.socket(Address::SocketType::Stream); | ||
| EXPECT_CALL(socket_, fd()).WillRepeatedly(Return(fd)); | ||
|
|
||
| for (Socket::SocketState state : when) { | ||
| if (option_name.has_value()) { | ||
| EXPECT_CALL(os_sys_calls_, | ||
| setsockopt_(_, socket_level, option_name.value(), _, sizeof(int))) | ||
| .WillOnce(Invoke([option_val](int, int, int, const void* optval, socklen_t) -> int { | ||
| EXPECT_EQ(option_val, *static_cast<const int*>(optval)); | ||
| return 0; | ||
| })); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, state)); | ||
| } else { | ||
| EXPECT_FALSE(socket_option.setOption(socket_, state)); | ||
| } | ||
| } | ||
|
|
||
| // The set of SocketState for which this option should not be set. Initialize to all | ||
| // the states, and remove states that are passed in. | ||
| std::list<Socket::SocketState> unset_socketstates{ | ||
| Socket::SocketState::PreBind, | ||
| Socket::SocketState::PostBind, | ||
| Socket::SocketState::Listening, | ||
| }; | ||
| unset_socketstates.remove_if( | ||
| [&](Socket::SocketState state) -> bool { return when.find(state) != when.end(); }); | ||
| for (Socket::SocketState state : unset_socketstates) { | ||
| EXPECT_CALL(os_sys_calls_, setsockopt_(_, _, _, _, _)).Times(0); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, state)); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| // We fail to set the option if the socket FD is bad. | ||
|
|
@@ -33,106 +69,74 @@ TEST_F(SocketOptionImplTest, BadFd) { | |
|
|
||
| // Nop when there are no socket options set. | ||
| TEST_F(SocketOptionImplTest, SetOptionEmptyNop) { | ||
| SocketOptionImpl socket_option{{}, {}}; | ||
| SocketOptionImpl socket_option{{}, {}, {}}; | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PostBind)); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::Listening)); | ||
| } | ||
|
|
||
| // We fail to set the option when the underlying setsockopt syscall fails. | ||
| TEST_F(SocketOptionImplTest, SetOptionTransparentFailure) { | ||
| SocketOptionImpl socket_option{true, {}}; | ||
| SocketOptionImpl socket_option{true, {}, {}}; | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } | ||
|
|
||
| // We fail to set the option when the underlying setsockopt syscall fails. | ||
| TEST_F(SocketOptionImplTest, SetOptionFreebindFailure) { | ||
| SocketOptionImpl socket_option{{}, true}; | ||
| SocketOptionImpl socket_option{{}, true, {}}; | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } | ||
|
|
||
| // We fail to set the tcp-fastopen option when the underlying setsockopt syscall fails. | ||
| TEST_F(SocketOptionImplTest, SetOptionTcpFastopenFailure) { | ||
| if (ENVOY_SOCKET_TCP_FASTOPEN.has_value()) { | ||
| SocketOptionImpl socket_option{{}, {}, 1}; | ||
| EXPECT_CALL(os_sys_calls_, setsockopt_(_, IPPROTO_TCP, ENVOY_SOCKET_TCP_FASTOPEN.value(), _, _)) | ||
| .WillOnce(Return(-1)); | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::Listening)); | ||
| } | ||
| } | ||
|
|
||
| // The happy path for setOption(); IP_TRANSPARENT is set to true. | ||
| TEST_F(SocketOptionImplTest, SetOptionTransparentSuccessTrue) { | ||
| SocketOptionImpl socket_option{true, {}}; | ||
| if (ENVOY_SOCKET_IP_TRANSPARENT.has_value()) { | ||
| Address::Ipv4Instance address("1.2.3.4", 5678); | ||
| const int fd = address.socket(Address::SocketType::Stream); | ||
| EXPECT_CALL(socket_, fd()).WillRepeatedly(Return(fd)); | ||
| EXPECT_CALL(os_sys_calls_, | ||
| setsockopt_(_, IPPROTO_IP, ENVOY_SOCKET_IP_TRANSPARENT.value(), _, sizeof(int))) | ||
| .WillOnce(Invoke([](int, int, int, const void* optval, socklen_t) -> int { | ||
| EXPECT_EQ(1, *static_cast<const int*>(optval)); | ||
| return 0; | ||
| })); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } else { | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } | ||
| SocketOptionImpl socket_option{true, {}, {}}; | ||
| testSetSocketOptionSuccess(socket_option, IPPROTO_IP, ENVOY_SOCKET_IP_TRANSPARENT, 1, | ||
| {Socket::SocketState::PreBind, Socket::SocketState::PostBind}); | ||
| } | ||
|
|
||
| // The happy path for setOption(); IP_FREEBIND is set to true. | ||
| TEST_F(SocketOptionImplTest, SetOptionFreebindSuccessTrue) { | ||
| SocketOptionImpl socket_option{{}, true}; | ||
| if (ENVOY_SOCKET_IP_FREEBIND.has_value()) { | ||
| Address::Ipv4Instance address("1.2.3.4", 5678); | ||
| const int fd = address.socket(Address::SocketType::Stream); | ||
| EXPECT_CALL(socket_, fd()).WillRepeatedly(Return(fd)); | ||
| EXPECT_CALL(os_sys_calls_, | ||
| setsockopt_(_, IPPROTO_IP, ENVOY_SOCKET_IP_FREEBIND.value(), _, sizeof(int))) | ||
| .WillOnce(Invoke([](int, int, int, const void* optval, socklen_t) -> int { | ||
| EXPECT_EQ(1, *static_cast<const int*>(optval)); | ||
| return 0; | ||
| })); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } else { | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } | ||
| SocketOptionImpl socket_option{{}, true, {}}; | ||
| testSetSocketOptionSuccess(socket_option, IPPROTO_IP, ENVOY_SOCKET_IP_FREEBIND, 1, | ||
| {Socket::SocketState::PreBind}); | ||
| } | ||
|
|
||
| // The happy path for setOpion(); IP_TRANSPARENT is set to false. | ||
| // The happy path for setOption(); TCP_FASTOPEN is set to true. | ||
| TEST_F(SocketOptionImplTest, SetOptionTcpFastopenSuccessTrue) { | ||
| SocketOptionImpl socket_option{{}, {}, 42}; | ||
| testSetSocketOptionSuccess(socket_option, IPPROTO_TCP, ENVOY_SOCKET_TCP_FASTOPEN, 42, | ||
| {Socket::SocketState::Listening}); | ||
| } | ||
|
|
||
| // The happy path for setOption(); IP_TRANSPARENT is set to false. | ||
| TEST_F(SocketOptionImplTest, SetOptionTransparentSuccessFalse) { | ||
| SocketOptionImpl socket_option{false, {}}; | ||
| if (ENVOY_SOCKET_IP_TRANSPARENT.has_value()) { | ||
| Address::Ipv4Instance address("1.2.3.4", 5678); | ||
| const int fd = address.socket(Address::SocketType::Stream); | ||
| EXPECT_CALL(socket_, fd()).WillRepeatedly(Return(fd)); | ||
| EXPECT_CALL(os_sys_calls_, | ||
| setsockopt_(_, IPPROTO_IP, ENVOY_SOCKET_IP_TRANSPARENT.value(), _, sizeof(int))) | ||
| .Times(2) | ||
| .WillRepeatedly(Invoke([](int, int, int, const void* optval, socklen_t) -> int { | ||
| EXPECT_EQ(0, *static_cast<const int*>(optval)); | ||
| return 0; | ||
| })); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PostBind)); | ||
| } else { | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::PostBind)); | ||
| } | ||
| SocketOptionImpl socket_option{false, {}, {}}; | ||
| testSetSocketOptionSuccess(socket_option, IPPROTO_IP, ENVOY_SOCKET_IP_TRANSPARENT, 0, | ||
| {Socket::SocketState::PreBind, Socket::SocketState::PostBind}); | ||
| } | ||
|
|
||
| // The happy path for setOpion(); IP_FREEBIND is set to false. | ||
| // The happy path for setOption(); IP_FREEBIND is set to false. | ||
| TEST_F(SocketOptionImplTest, SetOptionFreebindSuccessFalse) { | ||
| SocketOptionImpl socket_option{{}, false}; | ||
| if (ENVOY_SOCKET_IP_FREEBIND.has_value()) { | ||
| Address::Ipv4Instance address("1.2.3.4", 5678); | ||
| const int fd = address.socket(Address::SocketType::Stream); | ||
| EXPECT_CALL(socket_, fd()).WillRepeatedly(Return(fd)); | ||
| EXPECT_CALL(os_sys_calls_, | ||
| setsockopt_(_, IPPROTO_IP, ENVOY_SOCKET_IP_FREEBIND.value(), _, sizeof(int))) | ||
| .WillOnce(Invoke([](int, int, int, const void* optval, socklen_t) -> int { | ||
| EXPECT_EQ(0, *static_cast<const int*>(optval)); | ||
| return 0; | ||
| })); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } else { | ||
| EXPECT_FALSE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
| } | ||
| SocketOptionImpl socket_option{{}, false, {}}; | ||
| testSetSocketOptionSuccess(socket_option, IPPROTO_IP, ENVOY_SOCKET_IP_FREEBIND, 0, | ||
|
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. Nice cleanup! |
||
| {Socket::SocketState::PreBind}); | ||
| } | ||
|
|
||
| // Freebind settings have no effect on post-bind behavior. | ||
| TEST_F(SocketOptionImplTest, SetOptionFreebindPostBind) { | ||
| SocketOptionImpl socket_option{{}, true}; | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PostBind)); | ||
| // The happy path for setOpion(); TCP_FASTOPEN is set to false. | ||
| TEST_F(SocketOptionImplTest, SetOptionTcpFastopenSuccessFalse) { | ||
| SocketOptionImpl socket_option{{}, {}, 0}; | ||
| testSetSocketOptionSuccess(socket_option, IPPROTO_TCP, ENVOY_SOCKET_TCP_FASTOPEN, 0, | ||
| {Socket::SocketState::Listening}); | ||
| } | ||
|
|
||
| // If a platform doesn't suppport IPv4 socket option variant for an IPv4 address, we fail | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just merged envoyproxy/data-plane-api#539, so this can be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data-plane-api commit updated!