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.211 retrieving revision 1.221 diff -u -p -r1.211 -r1.221 --- src/sys/kern/uipc_socket.c 2012/07/09 04:35:13 1.211 +++ src/sys/kern/uipc_socket.c 2014/02/25 18:30:11 1.221 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.211 2012/07/09 04:35:13 chs Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.221 2014/02/25 18:30:11 pooka Exp $ */ /*- * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.211 2012/07/09 04:35:13 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.221 2014/02/25 18:30:11 pooka Exp $"); #include "opt_compat_netbsd.h" #include "opt_sock_counters.h" @@ -160,7 +160,7 @@ static void sopendfree_thread(void *); static kcondvar_t pendfree_thread_cv; static lwp_t *sopendfree_lwp; -static void sysctl_kern_somaxkva_setup(void); +static void sysctl_kern_socket_setup(void); static struct sysctllog *socket_sysctllog; static vsize_t @@ -416,7 +416,7 @@ socket_listener_cb(kauth_cred_t cred, ka /* Normal users can only drop their own connections. */ struct socket *so = (struct socket *)arg1; - if (proc_uidmatch(cred, so->so_cred)) + if (so->so_cred && proc_uidmatch(cred, so->so_cred) == 0) result = KAUTH_RESULT_ALLOW; break; @@ -453,7 +453,7 @@ void soinit(void) { - sysctl_kern_somaxkva_setup(); + sysctl_kern_socket_setup(); mutex_init(&so_pendfree_lock, MUTEX_DEFAULT, IPL_VM); softnet_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); @@ -538,6 +538,7 @@ socreate(int dom, struct socket **aso, i lock = lockso->so_lock; so->so_lock = lock; mutex_obj_hold(lock); + /* XXX Why is this not solock, to match sounlock? */ mutex_enter(lock); } else { /* Lock assigned and taken during PRU_ATTACH. */ @@ -585,6 +586,8 @@ fsocreate(int domain, struct socket **so fp->f_data = so; fd_affix(curproc, fp, fd); *fdout = fd; + if (flags & SOCK_NONBLOCK) + so->so_state |= SS_NBIO; } return error; } @@ -874,12 +877,10 @@ sosend(struct socket *so, struct mbuf *a struct mbuf *control, int flags, struct lwp *l) { struct mbuf **mp, *m; - struct proc *p; long space, len, resid, clen, mlen; int error, s, dontroute, atomic; short wakeup_state = 0; - p = l->l_proc; clen = 0; /* @@ -926,8 +927,7 @@ sosend(struct socket *so, struct mbuf *a } if ((so->so_state & SS_ISCONNECTED) == 0) { if (so->so_proto->pr_flags & PR_CONNREQUIRED) { - if ((so->so_state & SS_ISCONFIRMING) == 0 && - !(resid == 0 && clen != 0)) { + if (resid || clen == 0) { error = ENOTCONN; goto release; } @@ -1184,9 +1184,6 @@ soreceive(struct socket *so, struct mbuf */ s = splsoftnet(); solock(so); - if (so->so_state & SS_ISCONFIRMING && uio->uio_resid) - (*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL, l); - restart: if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0) { sounlock(so); @@ -1667,7 +1664,8 @@ sorflush(struct socket *so) static int sosetopt1(struct socket *so, const struct sockopt *sopt) { - int error = EINVAL, optval, opt; + int error = EINVAL, opt; + int optval = 0; /* XXX: gcc */ struct linger l; struct timeval tv; @@ -1909,6 +1907,7 @@ sogetopt1(struct socket *so, struct sock #ifdef SO_OTIMESTAMP case SO_OTIMESTAMP: #endif + case SO_ACCEPTCONN: error = sockopt_setint(sopt, (so->so_options & opt) ? 1 : 0); break; @@ -2366,6 +2365,7 @@ sopoll(struct socket *so, int events) #include static int sysctl_kern_somaxkva(SYSCTLFN_PROTO); +static int sysctl_kern_sbmax(SYSCTLFN_PROTO); /* * sysctl helper routine for kern.somaxkva. ensures that the given @@ -2396,16 +2396,35 @@ sysctl_kern_somaxkva(SYSCTLFN_ARGS) return (error); } +/* + * sysctl helper routine for kern.sbmax. Basically just ensures that + * any new value is not too small. + */ +static int +sysctl_kern_sbmax(SYSCTLFN_ARGS) +{ + int error, new_sbmax; + struct sysctlnode node; + + new_sbmax = sb_max; + node = *rnode; + node.sysctl_data = &new_sbmax; + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + if (error || newp == NULL) + return (error); + + KERNEL_LOCK(1, NULL); + error = sb_max_set(new_sbmax); + KERNEL_UNLOCK_ONE(NULL); + + return (error); +} + static void -sysctl_kern_somaxkva_setup(void) +sysctl_kern_socket_setup(void) { KASSERT(socket_sysctllog == NULL); - sysctl_createv(&socket_sysctllog, 0, NULL, NULL, - CTLFLAG_PERMANENT, - CTLTYPE_NODE, "kern", NULL, - NULL, 0, NULL, 0, - CTL_KERN, CTL_EOL); sysctl_createv(&socket_sysctllog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, @@ -2414,4 +2433,11 @@ sysctl_kern_somaxkva_setup(void) "used for socket buffers"), sysctl_kern_somaxkva, 0, NULL, 0, CTL_KERN, KERN_SOMAXKVA, CTL_EOL); + + sysctl_createv(&socket_sysctllog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "sbmax", + SYSCTL_DESCR("Maximum socket buffer size"), + sysctl_kern_sbmax, 0, NULL, 0, + CTL_KERN, KERN_SBMAX, CTL_EOL); }