Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.44.2.2 retrieving revision 1.50.4.4 diff -u -p -r1.44.2.2 -r1.50.4.4 --- src/sys/kern/uipc_socket.c 1999/06/21 14:46:36 1.44.2.2 +++ src/sys/kern/uipc_socket.c 2002/06/12 20:41:45 1.50.4.4 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.44.2.2 1999/06/21 14:46:36 perry Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.50.4.4 2002/06/12 20:41:45 he Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1990, 1993 @@ -54,6 +54,9 @@ struct pool socket_pool; +extern int somaxconn; /* patchable (XXX sysctl) */ +int somaxconn = SOMAXCONN; + void soinit() { @@ -74,13 +77,13 @@ int socreate(dom, aso, type, proto) int dom; struct socket **aso; - register int type; + int type; int proto; { struct proc *p = curproc; /* XXX */ - register struct protosw *prp; - register struct socket *so; - register int error; + struct protosw *prp; + struct socket *so; + int error; int s; if (proto) @@ -123,11 +126,11 @@ socreate(dom, aso, type, proto) } int -sobind(so, nam) +sobind(so, nam, p) struct socket *so; struct mbuf *nam; + struct proc *p; { - struct proc *p = curproc; /* XXX */ int s = splsoftnet(); int error; @@ -139,7 +142,7 @@ sobind(so, nam) int solisten(so, backlog) - register struct socket *so; + struct socket *so; int backlog; { int s = splsoftnet(), error; @@ -154,14 +157,14 @@ solisten(so, backlog) so->so_options |= SO_ACCEPTCONN; if (backlog < 0) backlog = 0; - so->so_qlimit = min(backlog, SOMAXCONN); + so->so_qlimit = min(backlog, somaxconn); splx(s); return (0); } void sofree(so) - register struct socket *so; + struct socket *so; { if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) @@ -187,7 +190,7 @@ sofree(so) */ int soclose(so) - register struct socket *so; + struct socket *so; { struct socket *so2; int s = splsoftnet(); /* conservative */ @@ -255,11 +258,11 @@ soabort(so) int soaccept(so, nam) - register struct socket *so; + struct socket *so; struct mbuf *nam; { int s = splsoftnet(); - int error; + int error = 0; if ((so->so_state & SS_NOFDREF) == 0) panic("soaccept: !NOFDREF"); @@ -268,14 +271,15 @@ soaccept(so, nam) error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, (struct mbuf *)0, nam, (struct mbuf *)0, (struct proc *)0); else - error = 0; + nam->m_len = 0; + splx(s); return (error); } int soconnect(so, nam) - register struct socket *so; + struct socket *so; struct mbuf *nam; { struct proc *p = curproc; /* XXX */ @@ -304,7 +308,7 @@ soconnect(so, nam) int soconnect2(so1, so2) - register struct socket *so1; + struct socket *so1; struct socket *so2; { int s = splsoftnet(); @@ -319,7 +323,7 @@ soconnect2(so1, so2) int sodisconnect(so) - register struct socket *so; + struct socket *so; { int s = splsoftnet(); int error; @@ -360,7 +364,7 @@ bad: */ int sosend(so, addr, uio, top, control, flags) - register struct socket *so; + struct socket *so; struct mbuf *addr; struct uio *uio; struct mbuf *top; @@ -369,8 +373,8 @@ sosend(so, addr, uio, top, control, flag { struct proc *p = curproc; /* XXX */ struct mbuf **mp; - register struct mbuf *m; - register long space, len, resid; + struct mbuf *m; + long space, len, resid; int clen = 0, error, s, dontroute, mlen; int atomic = sosendallatonce(so) || top; @@ -552,19 +556,20 @@ out: */ int soreceive(so, paddr, uio, mp0, controlp, flagsp) - register struct socket *so; + struct socket *so; struct mbuf **paddr; struct uio *uio; struct mbuf **mp0; struct mbuf **controlp; int *flagsp; { - register struct mbuf *m, **mp; - register int flags, len, error, s, offset; + struct mbuf *m, **mp; + int flags, len, error, s, offset; struct protosw *pr = so->so_proto; struct mbuf *nextrecord; int moff, type = 0; int orig_resid = uio->uio_resid; + int mbuf_removed = 0; mp = mp0; if (paddr) @@ -679,6 +684,7 @@ dontblock: m = m->m_next; } else { sbfree(&so->so_rcv, m); + mbuf_removed = 1; if (paddr) { *paddr = m; so->so_rcv.sb_mb = m->m_next; @@ -697,6 +703,7 @@ dontblock: m = m->m_next; } else { sbfree(&so->so_rcv, m); + mbuf_removed = 1; if (controlp) { if (pr->pr_domain->dom_externalize && mtod(m, struct cmsghdr *)->cmsg_type == @@ -753,6 +760,24 @@ dontblock: splx(s); error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio); s = splsoftnet(); + if (error) { + /* + * If any part of the record has been removed + * (such as the MT_SONAME mbuf, which will + * happen when PR_ADDR, and thus also + * PR_ATOMIC, is set), then drop the entire + * record to maintain the atomicity of the + * receive operation. + * + * This avoids a later panic("receive 1a") + * when compiled with DIAGNOSTIC. + */ + if (m && mbuf_removed + && (pr->pr_flags & PR_ATOMIC)) + (void) sbdroprecord(&so->so_rcv); + + goto release; + } } else uio->uio_resid -= len; if (len == m->m_len - moff) { @@ -872,11 +897,11 @@ soshutdown(so, how) void sorflush(so) - register struct socket *so; + struct socket *so; { - register struct sockbuf *sb = &so->so_rcv; - register struct protosw *pr = so->so_proto; - register int s; + struct sockbuf *sb = &so->so_rcv; + struct protosw *pr = so->so_proto; + int s; struct sockbuf asb; sb->sb_flags |= SB_NOINTR; @@ -894,12 +919,12 @@ sorflush(so) int sosetopt(so, level, optname, m0) - register struct socket *so; + struct socket *so; int level, optname; struct mbuf *m0; { int error = 0; - register struct mbuf *m = m0; + struct mbuf *m = m0; if (level != SOL_SOCKET) { if (so->so_proto && so->so_proto->pr_ctloutput) @@ -1035,11 +1060,11 @@ bad: int sogetopt(so, level, optname, mp) - register struct socket *so; + struct socket *so; int level, optname; struct mbuf **mp; { - register struct mbuf *m; + struct mbuf *m; if (level != SOL_SOCKET) { if (so->so_proto && so->so_proto->pr_ctloutput) { @@ -1121,7 +1146,7 @@ sogetopt(so, level, optname, mp) void sohasoutofband(so) - register struct socket *so; + struct socket *so; { struct proc *p;