[BACK]Return to uipc_socket.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/uipc_socket.c between version 1.211.2.5 and 1.223

version 1.211.2.5, 2017/12/03 11:38:45 version 1.223, 2014/05/18 14:46:15
Line 73 
Line 73 
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
 #ifdef _KERNEL_OPT  
 #include "opt_compat_netbsd.h"  #include "opt_compat_netbsd.h"
 #include "opt_sock_counters.h"  #include "opt_sock_counters.h"
 #include "opt_sosend_loan.h"  #include "opt_sosend_loan.h"
 #include "opt_mbuftrace.h"  #include "opt_mbuftrace.h"
 #include "opt_somaxkva.h"  #include "opt_somaxkva.h"
 #include "opt_multiprocessor.h" /* XXX */  #include "opt_multiprocessor.h" /* XXX */
 #include "opt_sctp.h"  
 #endif  
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
Line 295  sopendfree_thread(void *v)
Line 292  sopendfree_thread(void *v)
   
                         for (; m != NULL; m = next) {                          for (; m != NULL; m = next) {
                                 next = m->m_next;                                  next = m->m_next;
                                 KASSERT((~m->m_flags & (M_EXT|M_EXT_PAGES)) ==                                  KASSERT((~m->m_flags & (M_EXT|M_EXT_PAGES)) == 0);
                                     0);  
                                 KASSERT(m->m_ext.ext_refcnt == 0);                                  KASSERT(m->m_ext.ext_refcnt == 0);
   
                                 rv += m->m_ext.ext_size;                                  rv += m->m_ext.ext_size;
Line 435  socket_listener_cb(kauth_cred_t cred, ka
Line 431  socket_listener_cb(kauth_cred_t cred, ka
   
         case KAUTH_REQ_NETWORK_SOCKET_OPEN:          case KAUTH_REQ_NETWORK_SOCKET_OPEN:
                 /* We allow "raw" routing/bluetooth sockets to anyone. */                  /* We allow "raw" routing/bluetooth sockets to anyone. */
                 switch ((u_long)arg1) {                  if ((u_long)arg1 == PF_ROUTE || (u_long)arg1 == PF_OROUTE
                 case PF_ROUTE:                      || (u_long)arg1 == PF_BLUETOOTH) {
                 case PF_OROUTE:  
                 case PF_BLUETOOTH:  
                 case PF_CAN:  
                         result = KAUTH_RESULT_ALLOW;                          result = KAUTH_RESULT_ALLOW;
                         break;                  } else {
                 default:  
                         /* Privileged, let secmodel handle this. */                          /* Privileged, let secmodel handle this. */
                         if ((u_long)arg2 == SOCK_RAW)                          if ((u_long)arg2 == SOCK_RAW)
                                 break;                                  break;
                         result = KAUTH_RESULT_ALLOW;  
                         break;  
                 }                  }
   
                   result = KAUTH_RESULT_ALLOW;
   
                 break;                  break;
   
         case KAUTH_REQ_NETWORK_SOCKET_CANSEE:          case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
Line 497  soinit1(void)
Line 490  soinit1(void)
  *   *
  * => Caller may specify another socket for lock sharing (must not be held).   * => Caller may specify another socket for lock sharing (must not be held).
  * => Returns the new socket without lock held.   * => Returns the new socket without lock held.
  */  */
 int  int
 socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l,  socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l,
          struct socket *lockso)           struct socket *lockso)
Line 545  socreate(int dom, struct socket **aso, i
Line 538  socreate(int dom, struct socket **aso, i
         uid = kauth_cred_geteuid(l->l_cred);          uid = kauth_cred_geteuid(l->l_cred);
         so->so_uidinfo = uid_find(uid);          so->so_uidinfo = uid_find(uid);
         so->so_cpid = l->l_proc->p_pid;          so->so_cpid = l->l_proc->p_pid;
           if (lockso != NULL) {
         /*                  /* Caller wants us to share a lock. */
          * Lock assigned and taken during PCB attach, unless we share  
          * the lock with another socket, e.g. socketpair(2) case.  
          */  
         if (lockso) {  
                 lock = lockso->so_lock;                  lock = lockso->so_lock;
                 so->so_lock = lock;                  so->so_lock = lock;
                 mutex_obj_hold(lock);                  mutex_obj_hold(lock);
                   /* XXX Why is this not solock, to match sounlock? */
                 mutex_enter(lock);                  mutex_enter(lock);
           } else {
                   /* Lock assigned and taken during PRU_ATTACH. */
         }          }
           error = (*prp->pr_usrreqs->pr_generic)(so, PRU_ATTACH, NULL,
         /* Attach the PCB (returns with the socket lock held). */              (struct mbuf *)(long)proto, NULL, l);
         error = (*prp->pr_usrreqs->pr_attach)(so, proto);  
         KASSERT(solocked(so));          KASSERT(solocked(so));
           if (error != 0) {
         if (error) {  
                 KASSERT(so->so_pcb == NULL);                  KASSERT(so->so_pcb == NULL);
                 so->so_state |= SS_NOFDREF;                  so->so_state |= SS_NOFDREF;
                 sofree(so);                  sofree(so);
Line 569  socreate(int dom, struct socket **aso, i
Line 559  socreate(int dom, struct socket **aso, i
         }          }
         so->so_cred = kauth_cred_dup(l->l_cred);          so->so_cred = kauth_cred_dup(l->l_cred);
         sounlock(so);          sounlock(so);
   
         *aso = so;          *aso = so;
         return 0;          return 0;
 }  }
Line 607  fsocreate(int domain, struct socket **so
Line 596  fsocreate(int domain, struct socket **so
         if (flags & SOCK_NONBLOCK) {          if (flags & SOCK_NONBLOCK) {
                 so->so_state |= SS_NBIO;                  so->so_state |= SS_NBIO;
         }          }
         fp->f_socket = so;          fp->f_data = so;
         fd_affix(curproc, fp, fd);          fd_affix(curproc, fp, fd);
   
         if (sop != NULL) {          if (sop != NULL) {
Line 631  sofamily(const struct socket *so)
Line 620  sofamily(const struct socket *so)
 }  }
   
 int  int
 sobind(struct socket *so, struct sockaddr *nam, struct lwp *l)  sobind(struct socket *so, struct mbuf *nam, struct lwp *l)
 {  {
         int     error;          int     error;
   
         solock(so);          solock(so);
         if (nam->sa_family != so->so_proto->pr_domain->dom_family) {          error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
                 sounlock(so);              PRU_BIND, NULL, nam, NULL, l);
                 return EAFNOSUPPORT;  
         }  
         error = (*so->so_proto->pr_usrreqs->pr_bind)(so, nam, l);  
         sounlock(so);          sounlock(so);
         return error;          return error;
 }  }
Line 649  int
Line 635  int
 solisten(struct socket *so, int backlog, struct lwp *l)  solisten(struct socket *so, int backlog, struct lwp *l)
 {  {
         int     error;          int     error;
         short   oldopt, oldqlimit;  
   
         solock(so);          solock(so);
         if ((so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |          if ((so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |
             SS_ISDISCONNECTING)) != 0) {              SS_ISDISCONNECTING)) != 0) {
                 sounlock(so);                  sounlock(so);
                 return EINVAL;                  return EINVAL;
         }          }
         oldopt = so->so_options;          error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
         oldqlimit = so->so_qlimit;              PRU_LISTEN, NULL, NULL, NULL, l);
           if (error != 0) {
                   sounlock(so);
                   return error;
           }
         if (TAILQ_EMPTY(&so->so_q))          if (TAILQ_EMPTY(&so->so_q))
                 so->so_options |= SO_ACCEPTCONN;                  so->so_options |= SO_ACCEPTCONN;
         if (backlog < 0)          if (backlog < 0)
                 backlog = 0;                  backlog = 0;
         so->so_qlimit = min(backlog, somaxconn);          so->so_qlimit = min(backlog, somaxconn);
   
         error = (*so->so_proto->pr_usrreqs->pr_listen)(so, l);  
         if (error != 0) {  
                 so->so_options = oldopt;  
                 so->so_qlimit = oldqlimit;  
                 sounlock(so);  
                 return error;  
         }  
         sounlock(so);          sounlock(so);
         return 0;          return 0;
 }  }
Line 771  soclose(struct socket *so)
Line 752  soclose(struct socket *so)
         }          }
  drop:   drop:
         if (so->so_pcb) {          if (so->so_pcb) {
                 KASSERT(solocked(so));                  int error2 = (*so->so_proto->pr_usrreqs->pr_generic)(so,
                 (*so->so_proto->pr_usrreqs->pr_detach)(so);                      PRU_DETACH, NULL, NULL, NULL, NULL);
                   if (error == 0)
                           error = error2;
         }          }
  discard:   discard:
         KASSERT((so->so_state & SS_NOFDREF) == 0);          KASSERT((so->so_state & SS_NOFDREF) == 0);
Line 790  soabort(struct socket *so)
Line 773  soabort(struct socket *so)
 {  {
         u_int refs;          u_int refs;
         int error;          int error;
   
         KASSERT(solocked(so));          KASSERT(solocked(so));
         KASSERT(so->so_head == NULL);          KASSERT(so->so_head == NULL);
   
         so->so_aborting++;              /* XXX */          so->so_aborting++;              /* XXX */
         error = (*so->so_proto->pr_usrreqs->pr_abort)(so);          error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
               PRU_ABORT, NULL, NULL, NULL, NULL);
         refs = --so->so_aborting;       /* XXX */          refs = --so->so_aborting;       /* XXX */
         if (error || (refs == 0)) {          if (error || (refs == 0)) {
                 sofree(so);                  sofree(so);
Line 806  soabort(struct socket *so)
Line 790  soabort(struct socket *so)
 }  }
   
 int  int
 soaccept(struct socket *so, struct sockaddr *nam)  soaccept(struct socket *so, struct mbuf *nam)
 {  {
         int error;          int error;
   
Line 816  soaccept(struct socket *so, struct socka
Line 800  soaccept(struct socket *so, struct socka
         so->so_state &= ~SS_NOFDREF;          so->so_state &= ~SS_NOFDREF;
         if ((so->so_state & SS_ISDISCONNECTED) == 0 ||          if ((so->so_state & SS_ISDISCONNECTED) == 0 ||
             (so->so_proto->pr_flags & PR_ABRTACPTDIS) == 0)              (so->so_proto->pr_flags & PR_ABRTACPTDIS) == 0)
                 error = (*so->so_proto->pr_usrreqs->pr_accept)(so, nam);                  error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
                       PRU_ACCEPT, NULL, nam, NULL, NULL);
         else          else
                 error = ECONNABORTED;                  error = ECONNABORTED;
   
Line 824  soaccept(struct socket *so, struct socka
Line 809  soaccept(struct socket *so, struct socka
 }  }
   
 int  int
 soconnect(struct socket *so, struct sockaddr *nam, struct lwp *l)  soconnect(struct socket *so, struct mbuf *nam, struct lwp *l)
 {  {
         int error;          int error;
   
Line 840  soconnect(struct socket *so, struct sock
Line 825  soconnect(struct socket *so, struct sock
          */           */
         if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&          if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
             ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||              ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
             (error = sodisconnect(so)))) {              (error = sodisconnect(so))))
                 error = EISCONN;                  error = EISCONN;
         } else {          else
                 if (nam->sa_family != so->so_proto->pr_domain->dom_family) {                  error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
                         return EAFNOSUPPORT;                      PRU_CONNECT, NULL, nam, NULL, l);
                 }  
                 error = (*so->so_proto->pr_usrreqs->pr_connect)(so, nam, l);  
         }  
   
         return error;          return error;
 }  }
Line 857  soconnect2(struct socket *so1, struct so
Line 839  soconnect2(struct socket *so1, struct so
 {  {
         KASSERT(solocked2(so1, so2));          KASSERT(solocked2(so1, so2));
   
         return (*so1->so_proto->pr_usrreqs->pr_connect2)(so1, so2);          return (*so1->so_proto->pr_usrreqs->pr_generic)(so1,
               PRU_CONNECT2, NULL, (struct mbuf *)so2, NULL, NULL);
 }  }
   
 int  int
Line 872  sodisconnect(struct socket *so)
Line 855  sodisconnect(struct socket *so)
         } else if (so->so_state & SS_ISDISCONNECTING) {          } else if (so->so_state & SS_ISDISCONNECTING) {
                 error = EALREADY;                  error = EALREADY;
         } else {          } else {
                 error = (*so->so_proto->pr_usrreqs->pr_disconnect)(so);                  error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
                       PRU_DISCONNECT, NULL, NULL, NULL, NULL);
         }          }
         return (error);          return (error);
 }  }
Line 896  sodisconnect(struct socket *so)
Line 880  sodisconnect(struct socket *so)
  * Data and control buffers are freed on return.   * Data and control buffers are freed on return.
  */   */
 int  int
 sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,  sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
         struct mbuf *top, struct mbuf *control, int flags, struct lwp *l)          struct mbuf *control, int flags, struct lwp *l)
 {  {
         struct mbuf     **mp, *m;          struct mbuf     **mp, *m;
         long            space, len, resid, clen, mlen;          long            space, len, resid, clen, mlen;
Line 954  sosend(struct socket *so, struct sockadd
Line 938  sosend(struct socket *so, struct sockadd
                                         error = ENOTCONN;                                          error = ENOTCONN;
                                         goto release;                                          goto release;
                                 }                                  }
                         } else if (addr == NULL) {                          } else if (addr == 0) {
                                 error = EDESTADDRREQ;                                  error = EDESTADDRREQ;
                                 goto release;                                  goto release;
                         }                          }
Line 1002  sosend(struct socket *so, struct sockadd
Line 986  sosend(struct socket *so, struct sockadd
                                         m = m_gethdr(M_WAIT, MT_DATA);                                          m = m_gethdr(M_WAIT, MT_DATA);
                                         mlen = MHLEN;                                          mlen = MHLEN;
                                         m->m_pkthdr.len = 0;                                          m->m_pkthdr.len = 0;
                                         m_reset_rcvif(m);                                          m->m_pkthdr.rcvif = NULL;
                                 } else {                                  } else {
                                         m = m_get(M_WAIT, MT_DATA);                                          m = m_get(M_WAIT, MT_DATA);
                                         mlen = MLEN;                                          mlen = MLEN;
Line 1068  sosend(struct socket *so, struct sockadd
Line 1052  sosend(struct socket *so, struct sockadd
                                 so->so_options |= SO_DONTROUTE;                                  so->so_options |= SO_DONTROUTE;
                         if (resid > 0)                          if (resid > 0)
                                 so->so_state |= SS_MORETOCOME;                                  so->so_state |= SS_MORETOCOME;
                         if (flags & MSG_OOB) {                          error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
                                 error = (*so->so_proto->pr_usrreqs->pr_sendoob)(                              (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
                                     so, top, control);                              top, addr, control, curlwp);
                         } else {  
                                 error = (*so->so_proto->pr_usrreqs->pr_send)(so,  
                                     top, addr, control, l);  
                         }  
                         if (dontroute)                          if (dontroute)
                                 so->so_options &= ~SO_DONTROUTE;                                  so->so_options &= ~SO_DONTROUTE;
                         if (resid > 0)                          if (resid > 0)
Line 1186  soreceive(struct socket *so, struct mbuf
Line 1166  soreceive(struct socket *so, struct mbuf
         if (flags & MSG_OOB) {          if (flags & MSG_OOB) {
                 m = m_get(M_WAIT, MT_DATA);                  m = m_get(M_WAIT, MT_DATA);
                 solock(so);                  solock(so);
                 error = (*pr->pr_usrreqs->pr_recvoob)(so, m, flags & MSG_PEEK);                  error = (*pr->pr_usrreqs->pr_generic)(so, PRU_RCVOOB, m,
                       (struct mbuf *)(long)(flags & MSG_PEEK), NULL, l);
                 sounlock(so);                  sounlock(so);
                 if (error)                  if (error)
                         goto bad;                          goto bad;
Line 1328  soreceive(struct socket *so, struct mbuf
Line 1309  soreceive(struct socket *so, struct mbuf
                                 m->m_next = NULL;                                  m->m_next = NULL;
                                 m = so->so_rcv.sb_mb;                                  m = so->so_rcv.sb_mb;
                         } else {                          } else {
                                 m = so->so_rcv.sb_mb = m_free(m);                                  MFREE(m, so->so_rcv.sb_mb);
                                   m = so->so_rcv.sb_mb;
                         }                          }
                         sbsync(&so->so_rcv, nextrecord);                          sbsync(&so->so_rcv, nextrecord);
                 }                  }
         }          }
         if (pr->pr_flags & PR_ADDR_OPT) {  
                 /*  
                  * For SCTP we may be getting a  
                  * whole message OR a partial delivery.  
                  */  
                 if (m->m_type == MT_SONAME) {  
                         orig_resid = 0;  
                         if (flags & MSG_PEEK) {  
                                 if (paddr)  
                                         *paddr = m_copy(m, 0, m->m_len);  
                                 m = m->m_next;  
                         } else {  
                                 sbfree(&so->so_rcv, m);  
                                 if (paddr) {  
                                         *paddr = m;  
                                         so->so_rcv.sb_mb = m->m_next;  
                                         m->m_next = 0;  
                                         m = so->so_rcv.sb_mb;  
                                 } else {  
                                         m = so->so_rcv.sb_mb = m_free(m);  
                                 }  
                         }  
                 }  
         }  
   
         /*          /*
          * Process one or more MT_CONTROL mbufs present before any data mbufs           * Process one or more MT_CONTROL mbufs present before any data mbufs
Line 1411  soreceive(struct socket *so, struct mbuf
Line 1369  soreceive(struct socket *so, struct mbuf
                                  */                                   */
                                 if (dom->dom_dispose != NULL &&                                  if (dom->dom_dispose != NULL &&
                                     type == SCM_RIGHTS) {                                      type == SCM_RIGHTS) {
                                         sounlock(so);                                          sounlock(so);
                                         (*dom->dom_dispose)(cm);                                          (*dom->dom_dispose)(cm);
                                         solock(so);                                          solock(so);
                                 }                                  }
Line 1491  soreceive(struct socket *so, struct mbuf
Line 1449  soreceive(struct socket *so, struct mbuf
                 if (len == m->m_len - moff) {                  if (len == m->m_len - moff) {
                         if (m->m_flags & M_EOR)                          if (m->m_flags & M_EOR)
                                 flags |= MSG_EOR;                                  flags |= MSG_EOR;
 #ifdef SCTP  
                         if (m->m_flags & M_NOTIFICATION)  
                                 flags |= MSG_NOTIFICATION;  
 #endif /* SCTP */  
                         if (flags & MSG_PEEK) {                          if (flags & MSG_PEEK) {
                                 m = m->m_next;                                  m = m->m_next;
                                 moff = 0;                                  moff = 0;
Line 1507  soreceive(struct socket *so, struct mbuf
Line 1461  soreceive(struct socket *so, struct mbuf
                                         so->so_rcv.sb_mb = m = m->m_next;                                          so->so_rcv.sb_mb = m = m->m_next;
                                         *mp = NULL;                                          *mp = NULL;
                                 } else {                                  } else {
                                         m = so->so_rcv.sb_mb = m_free(m);                                          MFREE(m, so->so_rcv.sb_mb);
                                           m = so->so_rcv.sb_mb;
                                 }                                  }
                                 /*                                  /*
                                  * If m != NULL, we also know that                                   * If m != NULL, we also know that
Line 1579  soreceive(struct socket *so, struct mbuf
Line 1534  soreceive(struct socket *so, struct mbuf
                          * get it filled again.                           * get it filled again.
                          */                           */
                         if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb)                          if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb)
                                 (*pr->pr_usrreqs->pr_rcvd)(so, flags, l);                                  (*pr->pr_usrreqs->pr_generic)(so, PRU_RCVD,
                                       NULL, (struct mbuf *)(long)flags, NULL, l);
                         SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");                          SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
                         SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");                          SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
                         if (wakeup_state & SS_RESTARTSYS)                          if (wakeup_state & SS_RESTARTSYS)
Line 1620  soreceive(struct socket *so, struct mbuf
Line 1576  soreceive(struct socket *so, struct mbuf
                 SBLASTRECORDCHK(&so->so_rcv, "soreceive 4");                  SBLASTRECORDCHK(&so->so_rcv, "soreceive 4");
                 SBLASTMBUFCHK(&so->so_rcv, "soreceive 4");                  SBLASTMBUFCHK(&so->so_rcv, "soreceive 4");
                 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)                  if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
                         (*pr->pr_usrreqs->pr_rcvd)(so, flags, l);                          (*pr->pr_usrreqs->pr_generic)(so, PRU_RCVD, NULL,
                               (struct mbuf *)(long)flags, NULL, l);
         }          }
         if (orig_resid == uio->uio_resid && orig_resid &&          if (orig_resid == uio->uio_resid && orig_resid &&
             (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {              (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
Line 1654  soshutdown(struct socket *so, int how)
Line 1611  soshutdown(struct socket *so, int how)
                 error = 0;                  error = 0;
         }          }
         if (how == SHUT_WR || how == SHUT_RDWR)          if (how == SHUT_WR || how == SHUT_RDWR)
                 error = (*pr->pr_usrreqs->pr_shutdown)(so);                  error = (*pr->pr_usrreqs->pr_generic)(so,
                       PRU_SHUTDOWN, NULL, NULL, NULL, NULL);
   
         return error;          return error;
 }  }
Line 1725  sosetopt1(struct socket *so, const struc
Line 1683  sosetopt1(struct socket *so, const struc
                 KASSERT(solocked(so));                  KASSERT(solocked(so));
                 break;                  break;
   
         case SO_LINGER:          case SO_LINGER:
                 error = sockopt_get(sopt, &l, sizeof(l));                  error = sockopt_get(sopt, &l, sizeof(l));
                 solock(so);                  solock(so);
                 if (error)                  if (error)
                         break;                          break;
                 if (l.l_linger < 0 || l.l_linger > USHRT_MAX ||                  if (l.l_linger < 0 || l.l_linger > USHRT_MAX ||
                     l.l_linger > (INT_MAX / hz)) {                      l.l_linger > (INT_MAX / hz)) {
                         error = EDOM;                          error = EDOM;
                         break;                          break;
                 }                  }
                 so->so_linger = l.l_linger;                  so->so_linger = l.l_linger;
                 if (l.l_onoff)                  if (l.l_onoff)
                         so->so_options |= SO_LINGER;                          so->so_options |= SO_LINGER;
                 else                  else
                         so->so_options &= ~SO_LINGER;                          so->so_options &= ~SO_LINGER;
                 break;                  break;
   
         case SO_DEBUG:          case SO_DEBUG:
         case SO_KEEPALIVE:          case SO_KEEPALIVE:
Line 1919  so_setsockopt(struct lwp *l, struct sock
Line 1877  so_setsockopt(struct lwp *l, struct sock
   
         return error;          return error;
 }  }
   
 /*  /*
  * internal get SOL_SOCKET options   * internal get SOL_SOCKET options
  */   */
Line 2096  sockopt_destroy(struct sockopt *sopt)
Line 2054  sockopt_destroy(struct sockopt *sopt)
 /*  /*
  * set sockopt value   * set sockopt value
  *      - value is copied into sockopt   *      - value is copied into sockopt
  *      - memory is allocated when necessary, will not sleep   *      - memory is allocated when necessary, will not sleep
  */   */
 int  int
 sockopt_set(struct sockopt *sopt, const void *buf, size_t len)  sockopt_set(struct sockopt *sopt, const void *buf, size_t len)
Line 2221  filt_sordetach(struct knote *kn)
Line 2179  filt_sordetach(struct knote *kn)
 {  {
         struct socket   *so;          struct socket   *so;
   
         so = ((file_t *)kn->kn_obj)->f_socket;          so = ((file_t *)kn->kn_obj)->f_data;
         solock(so);          solock(so);
         SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);          SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
         if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))          if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
Line 2236  filt_soread(struct knote *kn, long hint)
Line 2194  filt_soread(struct knote *kn, long hint)
         struct socket   *so;          struct socket   *so;
         int rv;          int rv;
   
         so = ((file_t *)kn->kn_obj)->f_socket;          so = ((file_t *)kn->kn_obj)->f_data;
         if (hint != NOTE_SUBMIT)          if (hint != NOTE_SUBMIT)
                 solock(so);                  solock(so);
         kn->kn_data = so->so_rcv.sb_cc;          kn->kn_data = so->so_rcv.sb_cc;
Line 2248  filt_soread(struct knote *kn, long hint)
Line 2206  filt_soread(struct knote *kn, long hint)
                 rv = 1;                  rv = 1;
         else if (kn->kn_sfflags & NOTE_LOWAT)          else if (kn->kn_sfflags & NOTE_LOWAT)
                 rv = (kn->kn_data >= kn->kn_sdata);                  rv = (kn->kn_data >= kn->kn_sdata);
         else          else
                 rv = (kn->kn_data >= so->so_rcv.sb_lowat);                  rv = (kn->kn_data >= so->so_rcv.sb_lowat);
         if (hint != NOTE_SUBMIT)          if (hint != NOTE_SUBMIT)
                 sounlock(so);                  sounlock(so);
Line 2260  filt_sowdetach(struct knote *kn)
Line 2218  filt_sowdetach(struct knote *kn)
 {  {
         struct socket   *so;          struct socket   *so;
   
         so = ((file_t *)kn->kn_obj)->f_socket;          so = ((file_t *)kn->kn_obj)->f_data;
         solock(so);          solock(so);
         SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);          SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);
         if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))          if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))
Line 2275  filt_sowrite(struct knote *kn, long hint
Line 2233  filt_sowrite(struct knote *kn, long hint
         struct socket   *so;          struct socket   *so;
         int rv;          int rv;
   
         so = ((file_t *)kn->kn_obj)->f_socket;          so = ((file_t *)kn->kn_obj)->f_data;
         if (hint != NOTE_SUBMIT)          if (hint != NOTE_SUBMIT)
                 solock(so);                  solock(so);
         kn->kn_data = sbspace(&so->so_snd);          kn->kn_data = sbspace(&so->so_snd);
Line 2304  filt_solisten(struct knote *kn, long hin
Line 2262  filt_solisten(struct knote *kn, long hin
         struct socket   *so;          struct socket   *so;
         int rv;          int rv;
   
         so = ((file_t *)kn->kn_obj)->f_socket;          so = ((file_t *)kn->kn_obj)->f_data;
   
         /*          /*
          * Set kn_data to number of incoming connections, not           * Set kn_data to number of incoming connections, not
Line 2319  filt_solisten(struct knote *kn, long hin
Line 2277  filt_solisten(struct knote *kn, long hin
         return rv;          return rv;
 }  }
   
 static const struct filterops solisten_filtops = {  static const struct filterops solisten_filtops =
         .f_isfd = 1,          { 1, NULL, filt_sordetach, filt_solisten };
         .f_attach = NULL,  static const struct filterops soread_filtops =
         .f_detach = filt_sordetach,          { 1, NULL, filt_sordetach, filt_soread };
         .f_event = filt_solisten,  static const struct filterops sowrite_filtops =
 };          { 1, NULL, filt_sowdetach, filt_sowrite };
   
 static const struct filterops soread_filtops = {  
         .f_isfd = 1,  
         .f_attach = NULL,  
         .f_detach = filt_sordetach,  
         .f_event = filt_soread,  
 };  
   
 static const struct filterops sowrite_filtops = {  
         .f_isfd = 1,  
         .f_attach = NULL,  
         .f_detach = filt_sowdetach,  
         .f_event = filt_sowrite,  
 };  
   
 int  int
 soo_kqfilter(struct file *fp, struct knote *kn)  soo_kqfilter(struct file *fp, struct knote *kn)
Line 2346  soo_kqfilter(struct file *fp, struct kno
Line 2290  soo_kqfilter(struct file *fp, struct kno
         struct socket   *so;          struct socket   *so;
         struct sockbuf  *sb;          struct sockbuf  *sb;
   
         so = ((file_t *)kn->kn_obj)->f_socket;          so = ((file_t *)kn->kn_obj)->f_data;
         solock(so);          solock(so);
         switch (kn->kn_filter) {          switch (kn->kn_filter) {
         case EVFILT_READ:          case EVFILT_READ:
Line 2424  sopoll(struct socket *so, int events)
Line 2368  sopoll(struct socket *so, int events)
         return revents;          return revents;
 }  }
   
 struct mbuf **  
 sbsavetimestamp(int opt, struct mbuf *m, struct mbuf **mp)  
 {  
         struct timeval tv;  
         microtime(&tv);  
   
 #ifdef SO_OTIMESTAMP  
         if (opt & SO_OTIMESTAMP) {  
                 struct timeval50 tv50;  
   
                 timeval_to_timeval50(&tv, &tv50);  
                 *mp = sbcreatecontrol(&tv50, sizeof(tv50),  
                     SCM_OTIMESTAMP, SOL_SOCKET);  
                 if (*mp)  
                         mp = &(*mp)->m_next;  
         } else  
 #endif  
   
         if (opt & SO_TIMESTAMP) {  
                 *mp = sbcreatecontrol(&tv, sizeof(tv),  
                     SCM_TIMESTAMP, SOL_SOCKET);  
                 if (*mp)  
                         mp = &(*mp)->m_next;  
         }  
         return mp;  
 }  
   
   
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
   

Legend:
Removed from v.1.211.2.5  
changed lines
  Added in v.1.223

CVSweb <webmaster@jp.NetBSD.org>