From louie@whizzo.transsys.com  Tue May  7 22:04:10 1996
Received: from whizzo.transsys.com (whizzo.TransSys.COM [144.202.42.10])
          by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id WAA23510
          for <FreeBSD-gnats-submit@freebsd.org>; Tue, 7 May 1996 22:04:09 -0700 (PDT)
Received: (from louie@localhost) by whizzo.transsys.com (8.7.5/8.7.3) id BAA07011; Wed, 8 May 1996 01:04:08 -0400 (EDT)
Message-Id: <199605080504.BAA07011@whizzo.transsys.com>
Date: Wed, 8 May 1996 01:04:08 -0400 (EDT)
From: Louis Mamakos <louie@TransSys.COM>
Reply-To: louie@TransSys.COM
To: FreeBSD-gnats-submit@freebsd.org
Subject: Add socket option to timestamp arriving UDP data queued to socket
X-Send-Pr-Version: 3.2

>Number:         1179
>Category:       kern
>Synopsis:       Add socket option to timestamp arriving UDP data queued to socket
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    wollman
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May  7 22:10:01 PDT 1996
>Closed-Date:    Thu May 9 13:48:11 PDT 1996
>Last-Modified:  Thu May  9 18:20:03 PDT 1996
>Originator:     Louis Mamakos
>Release:        FreeBSD 2.2-CURRENT i386
>Organization:
>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


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: wollman 
State-Changed-When: Wed May 8 08:35:32 PDT 1996 
State-Changed-Why:  
Useful feature; I'll look at integrating it.  (I can imagine 
that some multimedia apps would like this sort of information 
as well.) 


Responsible-Changed-From-To: freebsd-bugs->wollman 
Responsible-Changed-By: wollman 
Responsible-Changed-When: Wed May 8 08:35:32 PDT 1996 
Responsible-Changed-Why:  
my area. 
State-Changed-From-To: analyzed->closed 
State-Changed-By: wollman 
State-Changed-When: Thu May 9 13:48:11 PDT 1996 
State-Changed-Why:  
Patch accepted. 

From: "JULIAN Elischer" <julian@ref.tfs.com>
To: louie@TransSys.COM
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/1179: Add socket option to timestamp arriving UDP data queued to socket
Date: Tue, 7 May 1996 22:39:10 -0700 (PDT)

  excellent!!!
 
 
 > 
 > 
 > 
 > >Number:         1179
 > >Category:       kern
 > >Synopsis:       Add socket option to timestamp arriving UDP data queued to socket
>Unformatted:
