From a47d370bb356ad40ce0eaa21c48c81a8aba801e4 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Mon, 6 Apr 2020 09:30:55 +0200 Subject: socket.7: Document SO_TIMESTAMPNS =========== DESCRIPTION =========== I added a paragraph for ``SO_TIMESTAMP``, and modified the paragraph for ``SIOCGSTAMP`` in relation to ``SO_TIMESTAMPNS``. I based the documentation on the existing ``SO_TIMESTAMP`` documentation, and on my experience using ``SO_TIMESTAMPNS``. I asked a question on stackoverflow, which helped me understand ``SO_TIMESTAMPNS``: https://stackoverflow.com/q/60971556/6872717 Testing of the feature being documented ======================================= I wrote a simple server and client test. In the client side, I connected a socket specifying ``SOCK_STREAM`` and ``"tcp"``. Then I enabled timestamp in ns: .. code-block:: c int enable = 1; if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPNS, &enable, sizeof(enable))) goto err; Then I prepared the msg header: .. code-block:: c char buf[BUFSIZ]; char cbuf[BUFSIZ]; struct msghdr msg; struct iovec iov; memset(buf, 0, ARRAY_BYTES(buf)); iov.iov_len = ARRAY_BYTES(buf) - 1; iov.iov_base = buf; msg.msg_name = NULL; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = cbuf; msg.msg_controllen = ARRAY_BYTES(cbuf); And got some times before and after receiving the msg: .. code-block:: c struct timespec tm_before, tm_recvmsg, tm_after, tm_msg; clock_gettime(CLOCK_REALTIME, &tm_before); usleep(500000); clock_gettime(CLOCK_REALTIME, &tm_recvmsg); n = recvmsg(sd, &msg, MSG_WAITALL); if (n < 0) goto err; usleep(1000000); clock_gettime(CLOCK_REALTIME, &tm_after); After that I read the timestamp of the msg: .. code-block:: c struct cmsghdr *cmsg; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPNS) { memcpy(&tm_msg, CMSG_DATA(cmsg), sizeof(tm_msg)); break; } } if (!cmsg) goto err; And finally printed the results: .. code-block:: c double tdiff; printf("%s\n", buf); tdiff = timespec_diff_ms(&tm_before, &tm_recvmsg); printf("tm_r - tm_b = %lf ms\n", tdiff); tdiff = timespec_diff_ms(&tm_before, &tm_after); printf("tm_a - tm_b = %lf ms\n", tdiff); tdiff = timespec_diff_ms(&tm_before, &tm_msg); printf("tm_m - tm_b = %lf ms\n", tdiff); Which printed: :: asdasdfasdfasdfadfgdfghfthgujty 6, 0; tm_r - tm_b = 500.000000 ms tm_a - tm_b = 1500.000000 ms tm_m - tm_b = 18.000000 ms System: :: Linux debian 5.4.0-4-amd64 #1 SMP Debian 5.4.19-1 (2020-02-13) x86_64 GNU/Linux gcc (Debian 9.3.0-8) 9.3.0 Signed-off-by: Michael Kerrisk --- man7/socket.7 | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'man7') diff --git a/man7/socket.7 b/man7/socket.7 index 7f309cb8ea..ee551dbcfd 100644 --- a/man7/socket.7 +++ b/man7/socket.7 @@ -26,11 +26,6 @@ .\" Seems to do something similar to getpeername(), but then .\" why is it necessary / how does it differ? .\" -.\" SO_TIMESTAMPNS (2.6.22) -.\" Documentation/networking/timestamping.txt -.\" commit 92f37fd2ee805aa77925c1e64fd56088b46094fc -.\" Author: Eric Dumazet -.\" .\" SO_TIMESTAMPING (2.6.30) .\" Documentation/networking/timestamping.txt .\" commit cb9eff097831007afb30d64373f29d99825d0068 @@ -946,6 +941,24 @@ See .BR cmsg (3) for details on control messages. .TP +.B SO_TIMESTAMPNS +Enable or disable the receiving of the +.B SO_TIMESTAMPNS +control message. +The timestamp control message is sent with level +.B SOL_SOCKET +and the +.I cmsg_data +field is a +.I "struct timespec" +indicating the +reception time of the last packet passed to the user in this call. +The clock used for the timestamp is +.BR CLOCK_REALTIME . +See +.BR cmsg (3) +for details on control messages. +.TP .B SO_TYPE Gets the socket type as an integer (e.g., .BR SOCK_STREAM ). @@ -1075,13 +1088,17 @@ See for a description of .IR "struct timeval" . .\" -This ioctl should be used only if the socket option +This ioctl should be used only if the socket options .B SO_TIMESTAMP -is not set on the socket. +and +.B SO_TIMESTAMPNS +are not set on the socket. Otherwise, it returns the timestamp of the last packet that was received while .B SO_TIMESTAMP -was not set, or it fails if no such packet has been received, +and +.B SO_TIMESTAMPNS +were not set, or it fails if no such packet has been received, (i.e., .BR ioctl (2) returns \-1 with -- cgit 1.2.3-korg