Date: Wed, 8 May 1996 01:04:08 -0400 (EDT) From: Louis Mamakos <louie@TransSys.COM> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/1179: Add socket option to timestamp arriving UDP data queued to socket Message-ID: <199605080504.BAA07011@whizzo.transsys.com> Resent-Message-ID: <199605080510.WAA23719@freefall.freebsd.org>
index | next in thread | raw e-mail
>Number: 1179
>Category: kern
>Synopsis: Add socket option to timestamp arriving UDP data queued to socket
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue May 7 22:10:01 PDT 1996
>Last-Modified:
>Originator: Louis Mamakos
>Organization:
>Release: FreeBSD 2.2-CURRENT i386
>Environment:
Desire for accurate time synchronization and timestamps.
>Description:
The attached code adds a new socket option which arranges for
data received on a UDP socket to be timestamped when it's queued
to the socket data structures. This then allows the associated
user process to read the data at it's leisure (or when it actually
is scheduled to run by the kernel), yet still have access to the
actual arrival time. The arrival time is critical to the operation
of xntpd, which uses the arrival timestamp to compute clock offset
and delay samples.
>How-To-Repeat:
Hmm.. By inspection, or you can install this code, plus a custom
version of xntpd which logs the delta times between the recorded
time from the socket option, and the time recored when it is
running the SIGIO handler.
>Fix:
Patches to a recent -current kernel. I've been running this code
for two weeks with no problems. For best results, the previous
PR for a fix to the recvmsg() system call code will allow
more than one piece of control information to be returned.
Index: kern/uipc_socket.c
===================================================================
RCS file: /usr/local/FreeBSD/cvs/CVSROOT/../src/sys/kern/uipc_socket.c,v
retrieving revision 1.17
diff -u -r1.17 uipc_socket.c
--- uipc_socket.c 1996/04/16 03:50:08 1.17
+++ uipc_socket.c 1996/05/04 04:07:50
@@ -893,6 +893,7 @@
case SO_REUSEADDR:
case SO_REUSEPORT:
case SO_OOBINLINE:
+ case SO_TIMESTAMP:
if (m == NULL || m->m_len < sizeof (int)) {
error = EINVAL;
goto bad;
@@ -1017,6 +1018,7 @@
case SO_REUSEPORT:
case SO_BROADCAST:
case SO_OOBINLINE:
+ case SO_TIMESTAMP:
*mtod(m, int *) = so->so_options & optname;
break;
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /usr/local/FreeBSD/cvs/CVSROOT/../src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.25
diff -u -r1.25 udp_usrreq.c
--- udp_usrreq.c 1996/05/02 05:54:14 1.25
+++ udp_usrreq.c 1996/05/04 04:08:12
@@ -95,6 +95,7 @@
struct mbuf *));
static void udp_notify __P((struct inpcb *, int));
static struct mbuf *udp_saveopt __P((caddr_t, int, int));
+static struct mbuf *udp_timestamp __P((void));
void
udp_init()
@@ -304,9 +305,14 @@
*/
udp_in.sin_port = uh->uh_sport;
udp_in.sin_addr = ip->ip_src;
- if (inp->inp_flags & INP_CONTROLOPTS) {
+ if (inp->inp_flags & INP_CONTROLOPTS
+ || inp->inp_socket->so_options & SO_TIMESTAMP) {
struct mbuf **mp = &opts;
+ if (inp->inp_socket->so_options & SO_TIMESTAMP) {
+ if (*mp = udp_timestamp())
+ mp = &(*mp)->m_next;
+ }
if (inp->inp_flags & INP_RECVDSTADDR) {
*mp = udp_saveopt((caddr_t) &ip->ip_dst,
sizeof(struct in_addr), IP_RECVDSTADDR);
@@ -369,6 +375,32 @@
cp->cmsg_len = size;
cp->cmsg_level = IPPROTO_IP;
cp->cmsg_type = type;
+ return (m);
+}
+
+/*
+ * Create an mbuf with the SCM_TIMESTAMP socket option data (struct timeval)
+ * inside. This really isn't UDP specific; but there's not really a better
+ * place for it yet..
+ */
+static struct mbuf *
+udp_timestamp()
+{
+ register struct cmsghdr *cp;
+ struct mbuf *m;
+ struct timeval tv;
+
+ MGET(m, M_DONTWAIT, MT_CONTROL);
+ if (m == 0)
+ return (struct mbuf *) 0;
+
+ microtime(&tv);
+ cp = (struct cmsghdr *) mtod(m, struct cmsghdr *);
+ cp->cmsg_len =
+ m->m_len = sizeof(*cp) + sizeof(struct timeval);
+ cp->cmsg_level = SOL_SOCKET;
+ cp->cmsg_type = SCM_TIMESTAMP;
+ (void) memcpy(CMSG_DATA(cp), &tv, sizeof(struct timeval));
return (m);
}
Index: sys/socket.h
===================================================================
RCS file: /usr/local/FreeBSD/cvs/CVSROOT/../src/sys/sys/socket.h,v
retrieving revision 1.10
diff -u -r1.10 socket.h
--- socket.h 1996/02/07 16:19:02 1.10
+++ socket.h 1996/04/09 03:06:21
@@ -63,6 +63,7 @@
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
+#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */
/*
* Additional options, not kept in so_options.
@@ -296,6 +297,7 @@
/* "Socket"-level control message types: */
#define SCM_RIGHTS 0x01 /* access rights (array of int) */
+#define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */
/*
* 4.3 compat sockaddr, move to compat file later
>Audit-Trail:
>Unformatted:
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605080504.BAA07011>
