diff options
-rw-r--r-- | sys/kern/uipc_socket.c | 4 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 35 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 36 | ||||
-rw-r--r-- | sys/sys/socket.h | 4 |
4 files changed, 64 insertions, 15 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 72a4567..b58eb51 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94 - * $Id: uipc_socket.c,v 1.16 1996/03/11 15:37:31 davidg Exp $ + * $Id: uipc_socket.c,v 1.17 1996/04/16 03:50:08 davidg Exp $ */ #include <sys/param.h> @@ -893,6 +893,7 @@ sosetopt(so, level, optname, m0) 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 @@ sogetopt(so, level, optname, mp) case SO_REUSEPORT: case SO_BROADCAST: case SO_OOBINLINE: + case SO_TIMESTAMP: *mtod(m, int *) = so->so_options & optname; break; diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index b366e94..6e17484 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 - * $Id: uipc_syscalls.c,v 1.15 1996/02/24 13:38:07 phk Exp $ + * $Id: uipc_syscalls.c,v 1.16 1996/03/11 15:37:33 davidg Exp $ */ #include "opt_ktrace.h" @@ -636,7 +636,8 @@ recvit(p, s, mp, namelenp, retsize) register struct iovec *iov; register int i; int len, error; - struct mbuf *from = 0, *control = 0; + struct mbuf *m, *from = 0, *control = 0; + caddr_t ctlbuf; #ifdef KTRACE struct iovec *ktriov = NULL; #endif @@ -735,17 +736,29 @@ recvit(p, s, mp, namelenp, retsize) } #endif len = mp->msg_controllen; - if (len <= 0 || control == 0) - len = 0; - else { - if (len >= control->m_len) - len = control->m_len; - else + m = control; + mp->msg_controllen = 0; + ctlbuf = (caddr_t) mp->msg_control; + + while (m && len > 0) { + unsigned int tocopy; + + if (len >= m->m_len) + tocopy = m->m_len; + else { mp->msg_flags |= MSG_CTRUNC; - error = copyout((caddr_t)mtod(control, caddr_t), - (caddr_t)mp->msg_control, (unsigned)len); + tocopy = len; + } + + if (error = copyout((caddr_t)mtod(m, caddr_t), + ctlbuf, tocopy)) + goto out; + + ctlbuf += tocopy; + len -= tocopy; + m = m->m_next; } - mp->msg_controllen = len; + mp->msg_controllen = ctlbuf - mp->msg_control; } out: if (from) diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index e2e52a9..e51b320 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 - * $Id: udp_usrreq.c,v 1.24 1996/05/02 05:31:13 fenner Exp $ + * $Id: udp_usrreq.c,v 1.25 1996/05/02 05:54:14 fenner Exp $ */ #include <sys/param.h> @@ -95,6 +95,7 @@ static int udp_output __P((struct inpcb *, struct mbuf *, struct mbuf *, 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_input(m, iphlen) */ 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); @@ -373,6 +379,32 @@ udp_saveopt(p, size, type) } /* + * 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); +} + +/* * Notify a udp user of an asynchronous error; * just wake up so that he can collect error status. */ diff --git a/sys/sys/socket.h b/sys/sys/socket.h index ed301e6..505a90f 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)socket.h 8.4 (Berkeley) 2/21/94 - * $Id: socket.h,v 1.9 1996/01/30 23:01:22 mpp Exp $ + * $Id: socket.h,v 1.10 1996/02/07 16:19:02 wollman Exp $ */ #ifndef _SYS_SOCKET_H_ @@ -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 @@ struct cmsghdr { /* "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 |