Commit d389a330 authored by Liang Zhu's avatar Liang Zhu Committed by Facebook Github Bot

exclude Unix Domain Socket from setErrMessageCB

Summary:
In the latest stable kernel 4.14.3 as of 2017-12-04, unix domain socket does not support MSG_ERRQUEUE. So recvmsg(MSG_ERRQUEUE) will read application data from unix doamin socket as error message, which breaks the message flow in application. This diff disable setErrMessageCB for Unix Domain Socket.

Both [[ https://github.com/torvalds/linux/blob/master/net/ipv4/tcp.c#L1782 | tcp_recvmsg ]] and [[ https://github.com/torvalds/linux/blob/master/net/ipv4/udp.c#L1571 | udp_recvmsg ]] will check flag MSG_ERRQUEUE and read from error queue.  However, there is nothing about MSG_ERRQUEUE in [[ https://github.com/torvalds/linux/blob/master/net/unix/af_unix.c#L2249 | af_unix ]].

Reviewed By: yfeldblum

Differential Revision: D6479465

fbshipit-source-id: eba2c8650e96466f2b361a42ddf90053d65f19bd
parent 67867996
main v2022.02.14.00 v2022.02.07.00 v2022.01.31.00 v2022.01.24.00 v2022.01.17.00 v2022.01.10.00 v2022.01.03.00 v2021.12.27.00 v2021.12.20.00 v2021.12.13.00 v2021.12.06.00 v2021.11.29.00 v2021.11.15.00 v2021.11.08.00 v2021.11.01.00 v2021.10.25.00 v2021.10.18.00 v2021.10.11.00 v2021.10.04.00 v2021.09.27.00 v2021.09.20.00 v2021.09.13.00 v2021.09.06.00 v2021.08.30.00 v2021.08.23.00 v2021.08.02.00 v2021.07.22.00 v2021.07.20.01 v2021.07.20.00 v2021.06.28.00 v2021.06.14.00 v2021.06.07.00 v2021.05.31.00 v2021.05.24.00 v2021.05.17.00 v2021.05.10.00 v2021.05.03.00 v2021.04.26.00 v2021.04.19.00 v2021.04.12.00 v2021.04.05.00 v2021.03.29.00 v2021.03.22.00 v2021.03.15.00 v2021.03.08.00 v2021.03.01.00 v2021.02.22.00 v2021.02.15.00 v2021.02.08.00 v2021.02.01.00 v2021.01.25.00 v2021.01.18.01 v2021.01.18.00 v2021.01.11.00 v2021.01.04.00 v2020.12.28.00 v2020.12.21.00 v2020.12.14.00 v2020.12.07.00 v2020.11.30.00 v2020.11.23.00 v2020.11.16.00 v2020.11.09.00 v2020.11.02.00 v2020.10.26.00 v2020.10.19.00 v2020.10.12.00 v2020.10.05.00 v2020.09.28.00 v2020.09.21.00 v2020.09.14.00 v2020.09.07.00 v2020.08.31.00 v2020.08.24.00 v2020.08.17.00 v2020.08.10.00 v2020.08.03.00 v2020.07.27.00 v2020.07.20.00 v2020.07.13.00 v2020.07.06.00 v2020.06.29.00 v2020.06.15.00 v2020.06.08.00 v2020.06.01.00 v2020.05.25.00 v2020.05.18.00 v2020.05.11.00 v2020.05.04.00 v2020.04.27.00 v2020.04.20.00 v2020.04.13.00 v2020.04.06.00 v2020.03.30.00 v2020.03.23.00 v2020.03.16.00 v2020.03.09.00 v2020.03.02.00 v2020.02.24.00 v2020.02.17.00 v2020.02.10.00 v2020.02.03.00 v2020.01.27.00 v2020.01.20.00 v2020.01.13.00 v2020.01.06.00 v2019.12.30.00 v2019.12.23.00 v2019.12.16.00 v2019.12.09.00 v2019.12.06.00 v2019.12.02.00 v2019.11.11.00 v2019.11.04.00 v2019.10.28.00 v2019.10.21.00 v2019.10.14.00 v2019.10.07.00 v2019.09.30.00 v2019.09.23.00 v2019.09.16.00 v2019.09.09.00 v2019.09.02.00 v2019.08.26.00 v2019.08.19.00 v2019.08.12.00 v2019.08.05.00 v2019.07.29.00 v2019.07.22.00 v2019.06.17.00 v2019.06.10.00 v2019.06.03.00 v2019.05.27.00 v2019.05.20.00 v2019.05.13.00 v2019.05.06.00 v2019.04.29.00 v2019.04.22.00 v2019.04.15.00 v2019.04.08.00 v2019.04.01.00 v2019.03.25.00 v2019.03.18.00 v2019.03.04.00 v2019.02.25.00 v2019.02.18.00 v2019.02.11.00 v2019.02.04.00 v2019.01.28.00 v2019.01.21.00 v2019.01.14.00 v2019.01.07.00 v2018.12.31.00 v2018.12.24.00 v2018.12.17.00 v2018.12.10.00 v2018.12.03.00 v2018.11.26.00 v2018.11.19.00 v2018.11.12.00 v2018.11.05.00 v2018.10.29.00 v2018.10.22.00 v2018.10.15.00 v2018.10.08.00 v2018.10.01.00 v2018.09.24.00 v2018.09.17.00 v2018.09.10.01 v2018.09.10.00 v2018.09.03.01 v2018.09.03.00 v2018.08.27.00 v2018.08.20.00 v2018.08.13.00 v2018.08.09.00 v2018.08.06.00 v2018.07.30.00 v2018.07.23.00 v2018.07.16.00 v2018.07.09.00 v2018.07.02.00 v2018.06.25.00 v2018.06.18.00 v2018.06.11.00 v2018.06.04.00 v2018.05.28.00 v2018.05.21.00 v2018.05.14.00 v2018.05.07.00 v2018.04.30.00 v2018.04.23.00 v2018.04.16.00 v2018.04.09.00 v2018.04.02.00 v2018.03.26.00 v2018.03.19.00 v2018.03.12.00 v2018.03.05.00 v2018.02.26.00 v2018.02.19.00 v2018.02.12.00 v2018.02.05.00 v2018.01.29.00 v2018.01.22.00 v2018.01.15.00 v2018.01.08.00 v2018.01.01.00 v2017.12.25.00 v2017.12.18.00 v2017.12.11.00
No related merge requests found
......@@ -662,6 +662,22 @@ void AsyncSocket::setErrMessageCB(ErrMessageCallback* callback) {
<< ", fd=" << fd_ << ", callback=" << callback
<< ", state=" << state_;
// In the latest stable kernel 4.14.3 as of 2017-12-04, unix domain
// socket does not support MSG_ERRQUEUE. So recvmsg(MSG_ERRQUEUE)
// will read application data from unix doamin socket as error
// message, which breaks the message flow in application. Feel free
// to remove the next code block if MSG_ERRQUEUE is added for unix
// domain socket in the future.
if (callback != nullptr) {
cacheLocalAddress();
if (localAddr_.getFamily() == AF_UNIX) {
LOG(ERROR) << "Failed to set ErrMessageCallback=" << callback
<< " for Unix Doamin Socket where MSG_ERRQUEUE is unsupported,"
<< " fd=" << fd_;
return;
}
}
// Short circuit if callback is the same as the existing errMessageCallback_.
if (callback == errMessageCallback_) {
return;
......
......@@ -3298,4 +3298,73 @@ TEST(AsyncSocketTest, SendMessageAncillaryData) {
magicString.end(),
transferredMagicString.begin()));
}
TEST(AsyncSocketTest, UnixDomainSocketErrMessageCB) {
// In the latest stable kernel 4.14.3 as of 2017-12-04, Unix Domain
// Socket (UDS) does not support MSG_ERRQUEUE. So
// recvmsg(MSG_ERRQUEUE) will read application data from UDS which
// breaks application message flow. To avoid this problem,
// AsyncSocket currently disables setErrMessageCB for UDS.
//
// This tests two things for UDS
// 1. setErrMessageCB fails
// 2. recvmsg(MSG_ERRQUEUE) reads application data
//
// Feel free to remove this test if UDS supports MSG_ERRQUEUE in the future.
int fd[2];
EXPECT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0);
ASSERT_NE(fd[0], -1);
ASSERT_NE(fd[1], -1);
SCOPE_EXIT {
close(fd[1]);
};
EXPECT_EQ(fcntl(fd[0], F_SETFL, O_NONBLOCK), 0);
EXPECT_EQ(fcntl(fd[1], F_SETFL, O_NONBLOCK), 0);
EventBase evb;
std::shared_ptr<AsyncSocket> socket = AsyncSocket::newSocket(&evb, fd[0]);
// setErrMessageCB should fail for unix domain socket
TestErrMessageCallback errMsgCB;
ASSERT_NE(&errMsgCB, nullptr);
socket->setErrMessageCB(&errMsgCB);
ASSERT_EQ(socket->getErrMessageCallback(), nullptr);
#ifdef FOLLY_HAVE_MSG_ERRQUEUE
// The following verifies that MSG_ERRQUEUE does not work for UDS,
// and recvmsg reads application data
union {
// Space large enough to hold an 'int'
char control[CMSG_SPACE(sizeof(int))];
struct cmsghdr cmh;
} r_u;
struct msghdr msgh;
struct iovec iov;
int recv_data = 0;
msgh.msg_control = r_u.control;
msgh.msg_controllen = sizeof(r_u.control);
msgh.msg_name = nullptr;
msgh.msg_namelen = 0;
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
iov.iov_base = &recv_data;
iov.iov_len = sizeof(recv_data);
// there is no data, recvmsg should fail
EXPECT_EQ(recvmsg(fd[1], &msgh, MSG_ERRQUEUE), -1);
EXPECT_TRUE(errno == EAGAIN || errno == EWOULDBLOCK);
// provide some application data, error queue should be empty if it exists
// However, UDS reads application data as error message
int test_data = 123456;
WriteCallback wcb;
socket->write(&wcb, &test_data, sizeof(test_data));
recv_data = 0;
ASSERT_NE(recvmsg(fd[1], &msgh, MSG_ERRQUEUE), -1);
ASSERT_EQ(recv_data, test_data);
#endif // FOLLY_HAVE_MSG_ERRQUEUE
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment