[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.48.2.4 and 1.50.4.5

version 1.48.2.4, 2001/03/12 13:31:38 version 1.50.4.5, 2002/09/18 16:04:53
Line 52 
Line 52 
 #include <sys/resourcevar.h>  #include <sys/resourcevar.h>
 #include <sys/pool.h>  #include <sys/pool.h>
   
 struct pool     socket_pool;  struct pool socket_pool;
   
 extern int      somaxconn;                      /* patchable (XXX sysctl) */  extern int somaxconn;                   /* patchable (XXX sysctl) */
 int             somaxconn = SOMAXCONN;  int somaxconn = SOMAXCONN;
   
 void  void
 soinit(void)  soinit()
 {  {
   
         pool_init(&socket_pool, sizeof(struct socket), 0, 0, 0,          pool_init(&socket_pool, sizeof(struct socket), 0, 0, 0,
Line 74  soinit(void)
Line 74  soinit(void)
  */   */
 /*ARGSUSED*/  /*ARGSUSED*/
 int  int
 socreate(int dom, struct socket **aso, int type, int proto)  socreate(dom, aso, type, proto)
           int dom;
           struct socket **aso;
           int type;
           int proto;
 {  {
         struct proc     *p;          struct proc *p = curproc;               /* XXX */
         struct protosw  *prp;          struct protosw *prp;
         struct socket   *so;          struct socket *so;
         int             error, s;          int error;
           int s;
   
         p = curproc;            /* XXX */  
         if (proto)          if (proto)
                 prp = pffindproto(dom, proto, type);                  prp = pffindproto(dom, proto, type);
         else          else
Line 122  socreate(int dom, struct socket **aso, i
Line 126  socreate(int dom, struct socket **aso, i
 }  }
   
 int  int
 sobind(struct socket *so, struct mbuf *nam, struct proc *p)  sobind(so, nam, p)
           struct socket *so;
           struct mbuf *nam;
           struct proc *p;
 {  {
         int     s, error;          int s = splsoftnet();
           int error;
   
         s = splsoftnet();  
         error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, (struct mbuf *)0,          error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, (struct mbuf *)0,
             nam, (struct mbuf *)0, p);              nam, (struct mbuf *)0, p);
         splx(s);          splx(s);
Line 134  sobind(struct socket *so, struct mbuf *n
Line 141  sobind(struct socket *so, struct mbuf *n
 }  }
   
 int  int
 solisten(struct socket *so, int backlog)  solisten(so, backlog)
           struct socket *so;
           int backlog;
 {  {
         int     s, error;          int s = splsoftnet(), error;
   
         s = splsoftnet();  
         error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, (struct mbuf *)0,          error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, (struct mbuf *)0,
             (struct mbuf *)0, (struct mbuf *)0, (struct proc *)0);              (struct mbuf *)0, (struct mbuf *)0, (struct proc *)0);
         if (error) {          if (error) {
Line 155  solisten(struct socket *so, int backlog)
Line 163  solisten(struct socket *so, int backlog)
 }  }
   
 void  void
 sofree(struct socket *so)  sofree(so)
           struct socket *so;
 {  {
   
         if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)          if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
Line 180  sofree(struct socket *so)
Line 189  sofree(struct socket *so)
  * Free socket when disconnect complete.   * Free socket when disconnect complete.
  */   */
 int  int
 soclose(struct socket *so)  soclose(so)
           struct socket *so;
 {  {
         struct socket   *so2;          struct socket *so2;
         int             s, error;          int s = splsoftnet();           /* conservative */
           int error = 0;
   
         error = 0;  
         s = splsoftnet();               /* conservative */  
         if (so->so_options & SO_ACCEPTCONN) {          if (so->so_options & SO_ACCEPTCONN) {
                 while ((so2 = so->so_q0.tqh_first) != 0) {                  while ((so2 = so->so_q0.tqh_first) != 0) {
                         (void) soqremque(so2, 0);                          (void) soqremque(so2, 0);
Line 218  soclose(struct socket *so)
Line 227  soclose(struct socket *so)
                         }                          }
                 }                  }
         }          }
  drop:  drop:
         if (so->so_pcb) {          if (so->so_pcb) {
                 int error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH,                  int error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
                     (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0,                      (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0,
Line 226  soclose(struct socket *so)
Line 235  soclose(struct socket *so)
                 if (error == 0)                  if (error == 0)
                         error = error2;                          error = error2;
         }          }
  discard:  discard:
         if (so->so_state & SS_NOFDREF)          if (so->so_state & SS_NOFDREF)
                 panic("soclose: NOFDREF");                  panic("soclose: NOFDREF");
         so->so_state |= SS_NOFDREF;          so->so_state |= SS_NOFDREF;
Line 239  soclose(struct socket *so)
Line 248  soclose(struct socket *so)
  * Must be called at splsoftnet...   * Must be called at splsoftnet...
  */   */
 int  int
 soabort(struct socket *so)  soabort(so)
           struct socket *so;
 {  {
   
         return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, (struct mbuf *)0,          return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, (struct mbuf *)0,
Line 247  soabort(struct socket *so)
Line 257  soabort(struct socket *so)
 }  }
   
 int  int
 soaccept(struct socket *so, struct mbuf *nam)  soaccept(so, nam)
           struct socket *so;
           struct mbuf *nam;
 {  {
         int     s, error;          int s = splsoftnet();
           int error = 0;
   
         error = 0;  
         s = splsoftnet();  
         if ((so->so_state & SS_NOFDREF) == 0)          if ((so->so_state & SS_NOFDREF) == 0)
                 panic("soaccept: !NOFDREF");                  panic("soaccept: !NOFDREF");
         so->so_state &= ~SS_NOFDREF;          so->so_state &= ~SS_NOFDREF;
Line 267  soaccept(struct socket *so, struct mbuf 
Line 278  soaccept(struct socket *so, struct mbuf 
 }  }
   
 int  int
 soconnect(struct socket *so, struct mbuf *nam)  soconnect(so, nam)
           struct socket *so;
           struct mbuf *nam;
 {  {
         struct proc     *p;          struct proc *p = curproc;               /* XXX */
         int             s, error;          int s;
           int error;
   
         p = curproc;            /* XXX */  
         if (so->so_options & SO_ACCEPTCONN)          if (so->so_options & SO_ACCEPTCONN)
                 return (EOPNOTSUPP);                  return (EOPNOTSUPP);
         s = splsoftnet();          s = splsoftnet();
Line 294  soconnect(struct socket *so, struct mbuf
Line 307  soconnect(struct socket *so, struct mbuf
 }  }
   
 int  int
 soconnect2(struct socket *so1, struct socket *so2)  soconnect2(so1, so2)
           struct socket *so1;
           struct socket *so2;
 {  {
         int     s, error;          int s = splsoftnet();
           int error;
   
         s = splsoftnet();  
         error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,          error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
             (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0,              (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0,
             (struct proc *)0);              (struct proc *)0);
Line 307  soconnect2(struct socket *so1, struct so
Line 322  soconnect2(struct socket *so1, struct so
 }  }
   
 int  int
 sodisconnect(struct socket *so)  sodisconnect(so)
           struct socket *so;
 {  {
         int     s, error;          int s = splsoftnet();
           int error;
   
         s = splsoftnet();  
         if ((so->so_state & SS_ISCONNECTED) == 0) {          if ((so->so_state & SS_ISCONNECTED) == 0) {
                 error = ENOTCONN;                  error = ENOTCONN;
                 goto bad;                  goto bad;
Line 323  sodisconnect(struct socket *so)
Line 339  sodisconnect(struct socket *so)
         error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,          error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
             (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0,              (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0,
             (struct proc *)0);              (struct proc *)0);
  bad:  bad:
         splx(s);          splx(s);
         return (error);          return (error);
 }  }
Line 347  sodisconnect(struct socket *so)
Line 363  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 mbuf *addr, struct uio *uio, struct mbuf *top,  sosend(so, addr, uio, top, control, flags)
         struct mbuf *control, int flags)          struct socket *so;
           struct mbuf *addr;
           struct uio *uio;
           struct mbuf *top;
           struct mbuf *control;
           int flags;
 {  {
         struct proc     *p;          struct proc *p = curproc;               /* XXX */
         struct mbuf     **mp, *m;          struct mbuf **mp;
         long            space, len, resid;          struct mbuf *m;
         int             clen, error, s, dontroute, mlen, atomic;          long space, len, resid;
           int clen = 0, error, s, dontroute, mlen;
         p = curproc;            /* XXX */          int atomic = sosendallatonce(so) || top;
         clen = 0;  
         atomic = sosendallatonce(so) || top;  
         if (uio)          if (uio)
                 resid = uio->uio_resid;                  resid = uio->uio_resid;
         else          else
Line 381  sosend(struct socket *so, struct mbuf *a
Line 401  sosend(struct socket *so, struct mbuf *a
                 clen = control->m_len;                  clen = control->m_len;
 #define snderr(errno)   { error = errno; splx(s); goto release; }  #define snderr(errno)   { error = errno; splx(s); goto release; }
   
  restart:  restart:
         if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)          if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
                 goto out;                  goto out;
         do {          do {
Line 449  sosend(struct socket *so, struct mbuf *a
Line 469  sosend(struct socket *so, struct mbuf *a
                                         len = min(MCLBYTES, resid);                                          len = min(MCLBYTES, resid);
 #else  #else
                                         if (atomic && top == 0) {                                          if (atomic && top == 0) {
                                                 len = min(MCLBYTES - max_hdr,                                                  len = min(MCLBYTES - max_hdr, resid);
                                                     resid);  
                                                 m->m_data += max_hdr;                                                  m->m_data += max_hdr;
                                         } else                                          } else
                                                 len = min(MCLBYTES, resid);                                                  len = min(MCLBYTES, resid);
Line 467  nopages:
Line 486  nopages:
                                         if (atomic && top == 0 && len < mlen)                                          if (atomic && top == 0 && len < mlen)
                                                 MH_ALIGN(m, len);                                                  MH_ALIGN(m, len);
                                 }                                  }
                                 error = uiomove(mtod(m, caddr_t), (int)len,                                  error = uiomove(mtod(m, caddr_t), (int)len, uio);
                                     uio);  
                                 resid = uio->uio_resid;                                  resid = uio->uio_resid;
                                 m->m_len = len;                                  m->m_len = len;
                                 *mp = m;                                  *mp = m;
Line 510  nopages:
Line 528  nopages:
                 } while (resid && space > 0);                  } while (resid && space > 0);
         } while (resid);          } while (resid);
   
  release:  release:
         sbunlock(&so->so_snd);          sbunlock(&so->so_snd);
  out:  out:
         if (top)          if (top)
                 m_freem(top);                  m_freem(top);
         if (control)          if (control)
Line 537  nopages:
Line 555  nopages:
  * only for the count in uio_resid.   * only for the count in uio_resid.
  */   */
 int  int
 soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,  soreceive(so, paddr, uio, mp0, controlp, flagsp)
         struct mbuf **mp0, struct mbuf **controlp, int *flagsp)          struct socket *so;
           struct mbuf **paddr;
           struct uio *uio;
           struct mbuf **mp0;
           struct mbuf **controlp;
           int *flagsp;
 {  {
         struct mbuf     *m, **mp;          struct mbuf *m, **mp;
         int             flags, len, error, s, offset, moff, type, orig_resid;          int flags, len, error, s, offset;
         struct protosw  *pr;          struct protosw *pr = so->so_proto;
         struct mbuf     *nextrecord;          struct mbuf *nextrecord;
           int moff, type = 0;
           int orig_resid = uio->uio_resid;
           int mbuf_removed = 0;
   
         pr = so->so_proto;  
         mp = mp0;          mp = mp0;
         type = 0;  
         orig_resid = uio->uio_resid;  
         if (paddr)          if (paddr)
                 *paddr = 0;                  *paddr = 0;
         if (controlp)          if (controlp)
Line 569  soreceive(struct socket *so, struct mbuf
Line 592  soreceive(struct socket *so, struct mbuf
                             (int) min(uio->uio_resid, m->m_len), uio);                              (int) min(uio->uio_resid, m->m_len), uio);
                         m = m_free(m);                          m = m_free(m);
                 } while (uio->uio_resid && error == 0 && m);                  } while (uio->uio_resid && error == 0 && m);
  bad:  bad:
                 if (m)                  if (m)
                         m_freem(m);                          m_freem(m);
                 return (error);                  return (error);
Line 580  soreceive(struct socket *so, struct mbuf
Line 603  soreceive(struct socket *so, struct mbuf
                 (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,                  (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
                     (struct mbuf *)0, (struct mbuf *)0, (struct proc *)0);                      (struct mbuf *)0, (struct mbuf *)0, (struct proc *)0);
   
  restart:  restart:
         if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)          if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
                 return (error);                  return (error);
         s = splsoftnet();          s = splsoftnet();
Line 643  soreceive(struct socket *so, struct mbuf
Line 666  soreceive(struct socket *so, struct mbuf
                         return (error);                          return (error);
                 goto restart;                  goto restart;
         }          }
  dontblock:  dontblock:
 #ifdef notyet /* XXXX */  #ifdef notyet /* XXXX */
         if (uio->uio_procp)          if (uio->uio_procp)
                 uio->uio_procp->p_stats->p_ru.ru_msgrcv++;                  uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
Line 661  soreceive(struct socket *so, struct mbuf
Line 684  soreceive(struct socket *so, struct mbuf
                         m = m->m_next;                          m = m->m_next;
                 } else {                  } else {
                         sbfree(&so->so_rcv, m);                          sbfree(&so->so_rcv, m);
                           mbuf_removed = 1;
                         if (paddr) {                          if (paddr) {
                                 *paddr = m;                                  *paddr = m;
                                 so->so_rcv.sb_mb = m->m_next;                                  so->so_rcv.sb_mb = m->m_next;
Line 679  soreceive(struct socket *so, struct mbuf
Line 703  soreceive(struct socket *so, struct mbuf
                         m = m->m_next;                          m = m->m_next;
                 } else {                  } else {
                         sbfree(&so->so_rcv, m);                          sbfree(&so->so_rcv, m);
                           mbuf_removed = 1;
                         if (controlp) {                          if (controlp) {
                                 if (pr->pr_domain->dom_externalize &&                                  if (pr->pr_domain->dom_externalize &&
                                     mtod(m, struct cmsghdr *)->cmsg_type ==                                      mtod(m, struct cmsghdr *)->cmsg_type ==
Line 735  soreceive(struct socket *so, struct mbuf
Line 760  soreceive(struct socket *so, struct mbuf
                         splx(s);                          splx(s);
                         error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);                          error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);
                         s = splsoftnet();                          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                  } else
                         uio->uio_resid -= len;                          uio->uio_resid -= len;
                 if (len == m->m_len - moff) {                  if (len == m->m_len - moff) {
Line 828  soreceive(struct socket *so, struct mbuf
Line 871  soreceive(struct socket *so, struct mbuf
   
         if (flagsp)          if (flagsp)
                 *flagsp |= flags;                  *flagsp |= flags;
  release:  release:
         sbunlock(&so->so_rcv);          sbunlock(&so->so_rcv);
         splx(s);          splx(s);
         return (error);          return (error);
 }  }
   
 int  int
 soshutdown(struct socket *so, int how)  soshutdown(so, how)
           struct socket *so;
           int how;
 {  {
         struct protosw  *pr;          struct protosw *pr = so->so_proto;
   
         pr = so->so_proto;  
         if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))          if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))
                 return (EINVAL);                  return (EINVAL);
   
Line 852  soshutdown(struct socket *so, int how)
Line 896  soshutdown(struct socket *so, int how)
 }  }
   
 void  void
 sorflush(struct socket *so)  sorflush(so)
           struct socket *so;
 {  {
         struct sockbuf  *sb, asb;          struct sockbuf *sb = &so->so_rcv;
         struct protosw  *pr;          struct protosw *pr = so->so_proto;
         int             s;          int s;
           struct sockbuf asb;
   
         sb = &so->so_rcv;  
         pr = so->so_proto;  
         sb->sb_flags |= SB_NOINTR;          sb->sb_flags |= SB_NOINTR;
         (void) sblock(sb, M_WAITOK);          (void) sblock(sb, M_WAITOK);
         s = splimp();          s = splimp();
Line 874  sorflush(struct socket *so)
Line 918  sorflush(struct socket *so)
 }  }
   
 int  int
 sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)  sosetopt(so, level, optname, m0)
           struct socket *so;
           int level, optname;
           struct mbuf *m0;
 {  {
         int             error;          int error = 0;
         struct mbuf     *m;          struct mbuf *m = m0;
   
         error = 0;  
         m = m0;  
         if (level != SOL_SOCKET) {          if (level != SOL_SOCKET) {
                 if (so->so_proto && so->so_proto->pr_ctloutput)                  if (so->so_proto && so->so_proto->pr_ctloutput)
                         return ((*so->so_proto->pr_ctloutput)                          return ((*so->so_proto->pr_ctloutput)
Line 1007  sosetopt(struct socket *so, int level, i
Line 1052  sosetopt(struct socket *so, int level, i
                         m = NULL;       /* freed by protocol */                          m = NULL;       /* freed by protocol */
                 }                  }
         }          }
  bad:  bad:
         if (m)          if (m)
                 (void) m_free(m);                  (void) m_free(m);
         return (error);          return (error);
 }  }
   
 int  int
 sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)  sogetopt(so, level, optname, mp)
           struct socket *so;
           int level, optname;
           struct mbuf **mp;
 {  {
         struct mbuf     *m;          struct mbuf *m;
   
         if (level != SOL_SOCKET) {          if (level != SOL_SOCKET) {
                 if (so->so_proto && so->so_proto->pr_ctloutput) {                  if (so->so_proto && so->so_proto->pr_ctloutput) {
Line 1097  sogetopt(struct socket *so, int level, i
Line 1145  sogetopt(struct socket *so, int level, i
 }  }
   
 void  void
 sohasoutofband(struct socket *so)  sohasoutofband(so)
           struct socket *so;
 {  {
         struct proc *p;          struct proc *p;
   

Legend:
Removed from v.1.48.2.4  
changed lines
  Added in v.1.50.4.5

CVSweb <webmaster@jp.NetBSD.org>