Tôi đang làm việc trong một dự án để nhận được và truyền thời gian dán tem từ NIC cho ổ cắm TCP như đã đề cập trong tài liệu Linux timestamping. Nhưng tất cả các tài liệu và kiểm tra mã hóa được thực hiện cho các ổ cắm UDP. Nhưng tôi nhận được timestamping Transmit cho NIC và không nhận được thời gian dán tem cho các gói tin TCP nhận được.Linux timestamping cho cổng TCP
My Interface hỗ trợ các tem thời gian sau
Time stamping parameters for enp4s0:
Capabilities:
hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 3
Hardware Transmit Timestamp Modes:
off (HWTSTAMP_TX_OFF)
on (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
none (HWTSTAMP_FILTER_NONE)
all (HWTSTAMP_FILTER_ALL)
tôi cho phép các timestamping cho NIC sau bind()
sử dụng ioctl(sockfd, SIOCSHWTSTAMP, &net_device);
với
memset(&net_device, 0, sizeof(net_device));
strncpy(net_device.ifr_name, interface_name, sizeof(net_device.ifr_name));
net_device.ifr_data = (void *)&tstconfig;
memset(&tstconfig, 0, sizeof(tstconfig));
tstconfig.tx_type = HWTSTAMP_TX_OFF;
tstconfig.rx_filter = HWTSTAMP_FILTER_ALL;
sau đó kích hoạt thời gian dập trong NIC qua setsockopt()
int opt= 0;
opt |= SOF_TIMESTAMPING_RX_HARDWARE;
opt |= SOF_TIMESTAMPING_RAW_HARDWARE;
if (setsockopt(sockfd, SOL_SOCKET, SO_TIMESTAMPING,
(char *)&opt, sizeof(opt))) {
error(1, 0, "setsockopt timestamping");
bail("setsockopt SO_TIMESTAMPING");
}
Sau khi lắng nghe() và chấp nhận(), tôi làm select()
, và kiểm tra xem fd
được rfds
sau đó gọi các recvmsg()
với các tùy chọn sau đây
int rc;
struct iovec vec[1];
struct msghdr msg;
char data[8192];
struct cmsghdr *cmsg;
union {
struct cmsghdr cm;
char control[256];
} cmsg_un;
vec[0].iov_base = data;
vec[0].iov_len = sizeof(data);
memset(&msg, 0, sizeof(msg));
memset(&from_addr, 0, sizeof(from_addr));
memset(&cmsg_un, 0, sizeof(cmsg_un));
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = vec;
msg.msg_iovlen = 1;
msg.msg_control = cmsg_un.control;
msg.msg_controllen = sizeof(cmsg_un.control);
rc = recvmsg(flow->fd, &msg, 0);
printf("tried reading %d bytes, got %d", bytes, rc);
if (msg.msg_flags & MSG_TRUNC) {
printf("received truncated message\n");
return 0;
}
if (msg.msg_flags & MSG_CTRUNC) {
printf("received truncated ancillary data\n");
return 0;
}
if (msg.msg_controllen <= 0) {
printf("`received short ancillary data (%ld/%ld)`\n",
(long)msg.msg_controllen, (long)sizeof(cmsg_un.control));
return 0;
}
Nhưng tôi luôn nhận được thông báo sau,
received short ancillary data (0/256)
Tôi không nhận được các dữ liệu phụ trợ từ recvmsg()
, tôi muốn biết liệu hỗ trợ linux TCP nhận được phần cứng thời gian dán tem cho NIC.
bạn có tìm thấy cách nào không? –