-
Notifications
You must be signed in to change notification settings - Fork 5.5k
connection: Set the SOL_IP,IP_TRANSPARENT option on listen sockets #2719
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 5 commits
474d515
b6ede70
b4d7134
fd77c94
899de9e
7f7eba8
4dd204a
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 |
|---|---|---|
|
|
@@ -33,20 +33,45 @@ 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)); | ||
| } | ||
|
|
||
| // We fail to set the option when the underlying setsockopt syscall fails. | ||
| TEST_F(SocketOptionImplTest, SetOptionTransparentFailure) { | ||
| 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)); | ||
| } | ||
|
|
||
| // The happy path for setOpion(); IP_FREEBIND is set true. | ||
| TEST_F(SocketOptionImplTest, SetOptionFreeebindSuccessTrue) { | ||
| SocketOptionImpl socket_option{true}; | ||
| // 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)); | ||
| } | ||
| } | ||
|
|
||
| // 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); | ||
|
|
@@ -63,17 +88,36 @@ TEST_F(SocketOptionImplTest, SetOptionFreeebindSuccessTrue) { | |
| } | ||
| } | ||
|
|
||
| // The happy path for setOpion(); IP_FREEBIND is set false. | ||
| TEST_F(SocketOptionImplTest, SetOptionFreeebindSuccessFalse) { | ||
| SocketOptionImpl socket_option{true}; | ||
| // The happy path for setOpion(); 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))) | ||
| .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)); | ||
| } | ||
| } | ||
|
|
||
| // The happy path for setOpion(); 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(1, *static_cast<const int*>(optval)); | ||
| EXPECT_EQ(0, *static_cast<const int*>(optval)); | ||
| return 0; | ||
| })); | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PreBind)); | ||
|
|
@@ -82,9 +126,15 @@ TEST_F(SocketOptionImplTest, SetOptionFreeebindSuccessFalse) { | |
| } | ||
| } | ||
|
|
||
| // Transparent settings have no effect on post-bind behavior. | ||
|
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 thought transparent does have an effect on both prebind and postbind?
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. Right. I will relax that.
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. Added a commit to support setting |
||
| TEST_F(SocketOptionImplTest, SetOptionTransparentPostBind) { | ||
| SocketOptionImpl socket_option{true, {}}; | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PostBind)); | ||
| } | ||
|
|
||
| // Freebind settings have no effect on post-bind behavior. | ||
| TEST_F(SocketOptionImplTest, SetOptionFreebindPostBind) { | ||
| SocketOptionImpl socket_option{true}; | ||
| SocketOptionImpl socket_option{{}, true}; | ||
| EXPECT_TRUE(socket_option.setOption(socket_, Socket::SocketState::PostBind)); | ||
| } | ||
|
|
||
|
|
||
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.
Is the v1 API absolutely required?
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.
We'll need it for Istio. Cf. istio/istio#4654 (review)