Commit e9d7342e authored by Brandon Schlinker's avatar Brandon Schlinker Committed by Facebook GitHub Bot

Stop relying on net_tstamp.h in AsyncSocket

Summary:
`net_tstamp.h` is incomplete on some platforms, particularly OSS.

One option would be to make `FOLLY_HAVE_SO_TIMESTAMPING` conditional on all of the timestamp flags being present. However, I'm instead going to just decouple this support from the underlying platform's headers.

Reviewed By: rsunkad

Differential Revision: D26971541

fbshipit-source-id: 01b24f57ab827aca42889138e4cca4d488ae0940
parent df81d76c
......@@ -41,7 +41,6 @@
#if defined(__linux__)
#include <linux/if_packet.h>
#include <linux/net_tstamp.h>
#include <linux/sockios.h>
#include <sys/ioctl.h>
#endif
......@@ -333,13 +332,13 @@ void AsyncSocket::SendMsgParamsCallback::getAncillaryData(
uint32_t sofFlags = 0;
if (byteEventsEnabled && isSet(flags, WriteFlags::TIMESTAMP_TX)) {
sofFlags = sofFlags | SOF_TIMESTAMPING_TX_SOFTWARE;
sofFlags = sofFlags | folly::netops::SOF_TIMESTAMPING_TX_SOFTWARE;
}
if (byteEventsEnabled && isSet(flags, WriteFlags::TIMESTAMP_ACK)) {
sofFlags = sofFlags | SOF_TIMESTAMPING_TX_ACK;
sofFlags = sofFlags | folly::netops::SOF_TIMESTAMPING_TX_ACK;
}
if (byteEventsEnabled && isSet(flags, WriteFlags::TIMESTAMP_SCHED)) {
sofFlags = sofFlags | SOF_TIMESTAMPING_TX_SCHED;
sofFlags = sofFlags | folly::netops::SOF_TIMESTAMPING_TX_SCHED;
}
msghdr msg;
......@@ -421,15 +420,15 @@ AsyncSocket::ByteEventHelper::processCmsg(
// map the type
folly::Optional<ByteEvent::Type> tsType;
switch (completeState.typeRaw) {
case SCM_TSTAMP_SND: {
case folly::netops::SCM_TSTAMP_SND: {
tsType = ByteEvent::Type::TX;
break;
}
case SCM_TSTAMP_ACK: {
case folly::netops::SCM_TSTAMP_ACK: {
tsType = ByteEvent::Type::ACK;
break;
}
case SCM_TSTAMP_SCHED: {
case folly::netops::SCM_TSTAMP_SCHED: {
tsType = ByteEvent::Type::SCHED;
break;
}
......@@ -1371,16 +1370,12 @@ void AsyncSocket::enableByteEvents() {
// SOF_TIMESTAMPING_SOFTWARE: get software timestamps if generated
// SOF_TIMESTAMPING_RAW_HARDWARE: get hardware timestamps if generated
// SOF_TIMESTAMPING_OPT_TX_SWHW: get both sw + hw timestamps if generated
// SOF_TIMESTAMPING_OPT_MULTIMSG: older version SOF_TIMESTAMPING_OPT_TX_SWHW
const uint32_t flags =
(SOF_TIMESTAMPING_OPT_ID | SOF_TIMESTAMPING_OPT_TSONLY |
SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RAW_HARDWARE
#if defined(SOF_TIMESTAMPING_OPT_TX_SWHW)
| SOF_TIMESTAMPING_OPT_TX_SWHW
#elif defined(SOF_TIMESTAMPING_OPT_MULTIMSG)
| SOF_TIMESTAMPING_OPT_MULTIMSG
#endif
);
(folly::netops::SOF_TIMESTAMPING_OPT_ID |
folly::netops::SOF_TIMESTAMPING_OPT_TSONLY |
folly::netops::SOF_TIMESTAMPING_SOFTWARE |
folly::netops::SOF_TIMESTAMPING_RAW_HARDWARE |
folly::netops::SOF_TIMESTAMPING_OPT_TX_SWHW);
socklen_t len = sizeof(flags);
const auto ret =
setSockOptVirtual(SOL_SOCKET, SO_TIMESTAMPING, &flags, len);
......
......@@ -47,8 +47,6 @@
#ifdef __linux__
#include <dlfcn.h>
#include <linux/errqueue.h>
#include <linux/net_tstamp.h>
#endif
#if FOLLY_OPENSSL_IS_110
......@@ -3175,13 +3173,13 @@ class AsyncSSLSocketByteEventTest : public ::testing::Test {
const uint32_t* sofFlags =
(reinterpret_cast<const uint32_t*>(CMSG_DATA(cmsg)));
WriteFlags flags = WriteFlags::NONE;
if (*sofFlags & SOF_TIMESTAMPING_TX_SCHED) {
if (*sofFlags & folly::netops::SOF_TIMESTAMPING_TX_SCHED) {
flags = flags | WriteFlags::TIMESTAMP_SCHED;
}
if (*sofFlags & SOF_TIMESTAMPING_TX_SOFTWARE) {
if (*sofFlags & folly::netops::SOF_TIMESTAMPING_TX_SOFTWARE) {
flags = flags | WriteFlags::TIMESTAMP_TX;
}
if (*sofFlags & SOF_TIMESTAMPING_TX_ACK) {
if (*sofFlags & folly::netops::SOF_TIMESTAMPING_TX_ACK) {
flags = flags | WriteFlags::TIMESTAMP_ACK;
}
......
......@@ -45,11 +45,6 @@
#include <folly/synchronization/Baton.h>
#include <folly/test/SocketAddressTestHelper.h>
#if defined(__linux__)
#include <linux/errqueue.h>
#include <linux/net_tstamp.h>
#endif
using std::min;
using std::string;
using std::unique_ptr;
......@@ -3239,9 +3234,11 @@ TEST_P(AsyncSocketErrMessageCallbackTest, ErrMessageCallback) {
// Enable timestamp notifications
ASSERT_NE(socket->getNetworkSocket(), NetworkSocket());
int flags = SOF_TIMESTAMPING_OPT_ID | SOF_TIMESTAMPING_OPT_TSONLY |
SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_CMSG |
SOF_TIMESTAMPING_TX_SCHED;
int flags = folly::netops::SOF_TIMESTAMPING_OPT_ID |
folly::netops::SOF_TIMESTAMPING_OPT_TSONLY |
folly::netops::SOF_TIMESTAMPING_SOFTWARE |
folly::netops::SOF_TIMESTAMPING_OPT_CMSG |
folly::netops::SOF_TIMESTAMPING_TX_SCHED;
SocketOptionKey tstampingOpt = {SOL_SOCKET, SO_TIMESTAMPING};
EXPECT_EQ(tstampingOpt.apply(socket->getNetworkSocket(), flags), 0);
......@@ -3475,13 +3472,13 @@ class AsyncSocketByteEventTest : public ::testing::Test {
const uint32_t* sofFlags =
(reinterpret_cast<const uint32_t*>(CMSG_DATA(cmsg)));
WriteFlags flags = WriteFlags::NONE;
if (*sofFlags & SOF_TIMESTAMPING_TX_SCHED) {
if (*sofFlags & folly::netops::SOF_TIMESTAMPING_TX_SCHED) {
flags = flags | WriteFlags::TIMESTAMP_SCHED;
}
if (*sofFlags & SOF_TIMESTAMPING_TX_SOFTWARE) {
if (*sofFlags & folly::netops::SOF_TIMESTAMPING_TX_SOFTWARE) {
flags = flags | WriteFlags::TIMESTAMP_TX;
}
if (*sofFlags & SOF_TIMESTAMPING_TX_ACK) {
if (*sofFlags & folly::netops::SOF_TIMESTAMPING_TX_ACK) {
flags = flags | WriteFlags::TIMESTAMP_ACK;
}
......@@ -3524,27 +3521,28 @@ TEST_F(AsyncSocketByteEventTest, GetMsgWriteFlags) {
// SCHED
{
auto msg = getMsg(SOF_TIMESTAMPING_TX_SCHED);
auto msg = getMsg(folly::netops::SOF_TIMESTAMPING_TX_SCHED);
EXPECT_EQ(WriteFlags::TIMESTAMP_SCHED, getMsgWriteFlags(msg));
}
// TX
{
auto msg = getMsg(SOF_TIMESTAMPING_TX_SOFTWARE);
auto msg = getMsg(folly::netops::SOF_TIMESTAMPING_TX_SOFTWARE);
EXPECT_EQ(WriteFlags::TIMESTAMP_TX, getMsgWriteFlags(msg));
}
// ACK
{
auto msg = getMsg(SOF_TIMESTAMPING_TX_ACK);
auto msg = getMsg(folly::netops::SOF_TIMESTAMPING_TX_ACK);
EXPECT_EQ(WriteFlags::TIMESTAMP_ACK, getMsgWriteFlags(msg));
}
// SCHED + TX + ACK
{
auto msg = getMsg(
SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_TX_ACK);
folly::netops::SOF_TIMESTAMPING_TX_SCHED |
folly::netops::SOF_TIMESTAMPING_TX_SOFTWARE |
folly::netops::SOF_TIMESTAMPING_TX_ACK);
EXPECT_EQ(
WriteFlags::TIMESTAMP_SCHED | WriteFlags::TIMESTAMP_TX |
WriteFlags::TIMESTAMP_ACK,
......@@ -3976,9 +3974,11 @@ TEST_F(AsyncSocketByteEventTest, FailTimestampsAlreadyEnabled) {
clientConn.connect();
// enable timestamps via setsockopt
const uint32_t flags = SOF_TIMESTAMPING_OPT_ID | SOF_TIMESTAMPING_OPT_TSONLY |
SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RAW_HARDWARE |
SOF_TIMESTAMPING_OPT_TX_SWHW;
const uint32_t flags = folly::netops::SOF_TIMESTAMPING_OPT_ID |
folly::netops::SOF_TIMESTAMPING_OPT_TSONLY |
folly::netops::SOF_TIMESTAMPING_SOFTWARE |
folly::netops::SOF_TIMESTAMPING_RAW_HARDWARE |
folly::netops::SOF_TIMESTAMPING_OPT_TX_SWHW;
const auto ret = clientConn.getRawSocket()->setSockOpt(
SOL_SOCKET, SO_TIMESTAMPING, &flags);
EXPECT_EQ(0, ret);
......@@ -4700,7 +4700,7 @@ class AsyncSocketByteEventHelperTest : public ::testing::Test {
};
TEST_F(AsyncSocketByteEventHelperTest, ByteOffsetThenTs) {
auto scmTs = cmsgForScmTimestamping(SCM_TSTAMP_SND, 0);
auto scmTs = cmsgForScmTimestamping(folly::netops::SCM_TSTAMP_SND, 0);
const auto softwareTsSec = std::chrono::seconds(59);
const auto softwareTsNs = std::chrono::nanoseconds(11);
auto serrTs = cmsgForSockExtendedErrTimestamping();
......@@ -4715,7 +4715,7 @@ TEST_F(AsyncSocketByteEventHelperTest, ByteOffsetThenTs) {
}
TEST_F(AsyncSocketByteEventHelperTest, TsThenByteOffset) {
auto scmTs = cmsgForScmTimestamping(SCM_TSTAMP_SND, 0);
auto scmTs = cmsgForScmTimestamping(folly::netops::SCM_TSTAMP_SND, 0);
const auto softwareTsSec = std::chrono::seconds(59);
const auto softwareTsNs = std::chrono::nanoseconds(11);
auto serrTs = cmsgForSockExtendedErrTimestamping();
......@@ -4730,7 +4730,7 @@ TEST_F(AsyncSocketByteEventHelperTest, TsThenByteOffset) {
}
TEST_F(AsyncSocketByteEventHelperTest, ByteEventsDisabled) {
auto scmTs = cmsgForScmTimestamping(SCM_TSTAMP_SND, 0);
auto scmTs = cmsgForScmTimestamping(folly::netops::SCM_TSTAMP_SND, 0);
const auto softwareTsSec = std::chrono::seconds(59);
const auto softwareTsNs = std::chrono::nanoseconds(11);
auto serrTs = cmsgForSockExtendedErrTimestamping();
......@@ -4751,7 +4751,8 @@ TEST_F(AsyncSocketByteEventHelperTest, ByteEventsDisabled) {
}
TEST_F(AsyncSocketByteEventHelperTest, IgnoreUnsupportedEvent) {
auto scmType = SCM_TSTAMP_ACK + 10; // imaginary new type of SCM event
auto scmType =
folly::netops::SCM_TSTAMP_ACK + 10; // imaginary new type of SCM event
auto scmTs = cmsgForScmTimestamping(scmType, 0);
const auto softwareTsSec = std::chrono::seconds(59);
const auto softwareTsNs = std::chrono::nanoseconds(11);
......@@ -4767,13 +4768,13 @@ TEST_F(AsyncSocketByteEventHelperTest, IgnoreUnsupportedEvent) {
EXPECT_FALSE(helper.processCmsg(serrTs, 1 /* rawBytesWritten */));
// change type, try again to prove this works
scmTs = cmsgForScmTimestamping(SCM_TSTAMP_ACK, 0);
scmTs = cmsgForScmTimestamping(folly::netops::SCM_TSTAMP_ACK, 0);
EXPECT_FALSE(helper.processCmsg(scmTs, 1 /* rawBytesWritten */));
EXPECT_TRUE(helper.processCmsg(serrTs, 1 /* rawBytesWritten */));
}
TEST_F(AsyncSocketByteEventHelperTest, ErrorDoubleScmCmsg) {
auto scmTs = cmsgForScmTimestamping(SCM_TSTAMP_SND, 0);
auto scmTs = cmsgForScmTimestamping(folly::netops::SCM_TSTAMP_SND, 0);
AsyncSocket::ByteEventHelper helper = {};
helper.byteEventsEnabled = true;
......@@ -4800,7 +4801,7 @@ TEST_F(AsyncSocketByteEventHelperTest, ErrorDoubleSerrCmsg) {
}
TEST_F(AsyncSocketByteEventHelperTest, ErrorExceptionSet) {
auto scmTs = cmsgForScmTimestamping(SCM_TSTAMP_SND, 0);
auto scmTs = cmsgForScmTimestamping(folly::netops::SCM_TSTAMP_SND, 0);
const auto softwareTsSec = std::chrono::seconds(59);
const auto softwareTsNs = std::chrono::nanoseconds(11);
auto serrTs = cmsgForSockExtendedErrTimestamping();
......@@ -4849,23 +4850,32 @@ class AsyncSocketByteEventHelperTimestampTest
// software + hardware timestamps
{
vals.emplace_back(SCM_TSTAMP_SCHED, ByteEventType::SCHED, true, true);
vals.emplace_back(SCM_TSTAMP_SND, ByteEventType::TX, true, true);
vals.emplace_back(SCM_TSTAMP_ACK, ByteEventType::ACK, true, true);
vals.emplace_back(
folly::netops::SCM_TSTAMP_SCHED, ByteEventType::SCHED, true, true);
vals.emplace_back(
folly::netops::SCM_TSTAMP_SND, ByteEventType::TX, true, true);
vals.emplace_back(
folly::netops::SCM_TSTAMP_ACK, ByteEventType::ACK, true, true);
}
// software ts only
{
vals.emplace_back(SCM_TSTAMP_SCHED, ByteEventType::SCHED, true, false);
vals.emplace_back(SCM_TSTAMP_SND, ByteEventType::TX, true, false);
vals.emplace_back(SCM_TSTAMP_ACK, ByteEventType::ACK, true, false);
vals.emplace_back(
folly::netops::SCM_TSTAMP_SCHED, ByteEventType::SCHED, true, false);
vals.emplace_back(
folly::netops::SCM_TSTAMP_SND, ByteEventType::TX, true, false);
vals.emplace_back(
folly::netops::SCM_TSTAMP_ACK, ByteEventType::ACK, true, false);
}
// hardware ts only
{
vals.emplace_back(SCM_TSTAMP_SCHED, ByteEventType::SCHED, false, true);
vals.emplace_back(SCM_TSTAMP_SND, ByteEventType::TX, false, true);
vals.emplace_back(SCM_TSTAMP_ACK, ByteEventType::ACK, false, true);
vals.emplace_back(
folly::netops::SCM_TSTAMP_SCHED, ByteEventType::SCHED, false, true);
vals.emplace_back(
folly::netops::SCM_TSTAMP_SND, ByteEventType::TX, false, true);
vals.emplace_back(
folly::netops::SCM_TSTAMP_ACK, ByteEventType::ACK, false, true);
}
return vals;
......@@ -5170,7 +5180,8 @@ TEST_P(AsyncSocketByteEventHelperOffsetTest, CheckCalculatedOffset) {
kernelByteOffset = kernelByteOffset % bytesPerOffsetWrap;
}
auto scmTs = cmsgForScmTimestamping(SCM_TSTAMP_SND, kernelByteOffset);
auto scmTs =
cmsgForScmTimestamping(folly::netops::SCM_TSTAMP_SND, kernelByteOffset);
const auto softwareTsSec = std::chrono::seconds(59);
const auto softwareTsNs = std::chrono::nanoseconds(11);
auto serrTs = cmsgForSockExtendedErrTimestamping();
......@@ -6210,8 +6221,9 @@ TEST(AsyncSocketTest, readAncillaryData) {
// Enable rx timestamp notifications
ASSERT_NE(socket->getNetworkSocket(), NetworkSocket());
int flags = SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_RX_HARDWARE;
int flags = folly::netops::SOF_TIMESTAMPING_SOFTWARE |
folly::netops::SOF_TIMESTAMPING_RX_SOFTWARE |
folly::netops::SOF_TIMESTAMPING_RX_HARDWARE;
SocketOptionKey tstampingOpt = {SOL_SOCKET, SO_TIMESTAMPING};
EXPECT_EQ(tstampingOpt.apply(socket->getNetworkSocket(), flags), 0);
......
......@@ -143,6 +143,8 @@ struct mmsghdr {
#ifdef FOLLY_HAVE_MSG_ERRQUEUE
namespace folly {
namespace netops {
/* Copied from uapi/linux/net_tstamp.h */
enum txtime_flags {
SOF_TXTIME_DEADLINE_MODE = (1 << 0),
SOF_TXTIME_REPORT_ERRORS = (1 << 1),
......@@ -151,6 +153,35 @@ enum txtime_flags {
SOF_TXTIME_FLAGS_MASK = (SOF_TXTIME_FLAGS_LAST - 1) | SOF_TXTIME_FLAGS_LAST
};
/* Copied from uapi/linux/net_tstamp.h */
enum timestamping_flags {
SOF_TIMESTAMPING_TX_HARDWARE = (1 << 0),
SOF_TIMESTAMPING_TX_SOFTWARE = (1 << 1),
SOF_TIMESTAMPING_RX_HARDWARE = (1 << 2),
SOF_TIMESTAMPING_RX_SOFTWARE = (1 << 3),
SOF_TIMESTAMPING_SOFTWARE = (1 << 4),
SOF_TIMESTAMPING_SYS_HARDWARE = (1 << 5),
SOF_TIMESTAMPING_RAW_HARDWARE = (1 << 6),
SOF_TIMESTAMPING_OPT_ID = (1 << 7),
SOF_TIMESTAMPING_TX_SCHED = (1 << 8),
SOF_TIMESTAMPING_TX_ACK = (1 << 9),
SOF_TIMESTAMPING_OPT_CMSG = (1 << 10),
SOF_TIMESTAMPING_OPT_TSONLY = (1 << 11),
SOF_TIMESTAMPING_OPT_STATS = (1 << 12),
SOF_TIMESTAMPING_OPT_PKTINFO = (1 << 13),
SOF_TIMESTAMPING_OPT_TX_SWHW = (1 << 14),
SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
};
/* Copied from uapi/linux/net_tstamp.h */
enum tstamp_flags {
SCM_TSTAMP_SND, /* driver passed skb to NIC, or HW */
SCM_TSTAMP_SCHED, /* data entered the packet scheduler */
SCM_TSTAMP_ACK, /* data acknowledged by peer */
};
struct sock_txtime {
__kernel_clockid_t clockid; /* reference clockid */
__u32 flags; /* as defined by enum txtime_flags */
......
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