Skip to content

Commit

Permalink
socket.7: Document SO_TIMESTAMPNS
Browse files Browse the repository at this point in the history
===========
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 <mtk.manpages@gmail.com>
  • Loading branch information
Alejandro Colomar authored and mkerrisk committed Apr 6, 2020
1 parent f3c2993 commit a47d370
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions man7/socket.7
Original file line number Diff line number Diff line change
Expand Up @@ -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 <dada1@cosmosbay.com>
.\"
.\" SO_TIMESTAMPING (2.6.30)
.\" Documentation/networking/timestamping.txt
.\" commit cb9eff097831007afb30d64373f29d99825d0068
Expand Down Expand Up @@ -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 ).
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit a47d370

Please sign in to comment.