Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / kern / uipc_usrreq.c
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *      From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94
34  * $FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.54.2.10 2003/03/04 17:28:09 nectar Exp $
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/domain.h>
41 #include <sys/fcntl.h>
42 #include <sys/malloc.h>         /* XXX must be before <sys/file.h> */
43 #include <sys/file.h>
44 #include <sys/filedesc.h>
45 #include <sys/mbuf.h>
46 #include <sys/namei.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/resourcevar.h>
52 #include <sys/stat.h>
53 #include <sys/sysctl.h>
54 #include <sys/un.h>
55 #include <sys/unpcb.h>
56 #include <sys/vnode.h>
57
58 #include <vm/vm_zone.h>
59
60 static  struct vm_zone *unp_zone;
61 static  unp_gen_t unp_gencnt;
62 static  u_int unp_count;
63
64 static  struct unp_head unp_shead, unp_dhead;
65
66 /*
67  * Unix communications domain.
68  *
69  * TODO:
70  *      SEQPACKET, RDM
71  *      rethink name space problems
72  *      need a proper out-of-band
73  *      lock pushdown
74  */
75 static struct   sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL };
76 static ino_t    unp_ino;                /* prototype for fake inode numbers */
77
78 static int     unp_attach __P((struct socket *));
79 static void    unp_detach __P((struct unpcb *));
80 static int     unp_bind __P((struct unpcb *,struct sockaddr *, struct proc *));
81 static int     unp_connect __P((struct socket *,struct sockaddr *,
82                                 struct proc *));
83 static void    unp_disconnect __P((struct unpcb *));
84 static void    unp_shutdown __P((struct unpcb *));
85 static void    unp_drop __P((struct unpcb *, int));
86 static void    unp_gc __P((void));
87 static void    unp_scan __P((struct mbuf *, void (*)(struct file *)));
88 static void    unp_mark __P((struct file *));
89 static void    unp_discard __P((struct file *));
90 static int     unp_internalize __P((struct mbuf *, struct proc *));
91 static int     unp_listen __P((struct unpcb *, struct proc *));
92
93 static int
94 uipc_abort(struct socket *so)
95 {
96         struct unpcb *unp = sotounpcb(so);
97
98         if (unp == 0)
99                 return EINVAL;
100         unp_drop(unp, ECONNABORTED);
101         unp_detach(unp);
102         sofree(so);
103         return 0;
104 }
105
106 static int
107 uipc_accept(struct socket *so, struct sockaddr **nam)
108 {
109         struct unpcb *unp = sotounpcb(so);
110
111         if (unp == 0)
112                 return EINVAL;
113
114         /*
115          * Pass back name of connected socket,
116          * if it was bound and we are still connected
117          * (our peer may have closed already!).
118          */
119         if (unp->unp_conn && unp->unp_conn->unp_addr) {
120                 *nam = dup_sockaddr((struct sockaddr *)unp->unp_conn->unp_addr,
121                                     1);
122         } else {
123                 *nam = dup_sockaddr((struct sockaddr *)&sun_noname, 1);
124         }
125         return 0;
126 }
127
128 static int
129 uipc_attach(struct socket *so, int proto, struct proc *p)
130 {
131         struct unpcb *unp = sotounpcb(so);
132
133         if (unp != 0)
134                 return EISCONN;
135         return unp_attach(so);
136 }
137
138 static int
139 uipc_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
140 {
141         struct unpcb *unp = sotounpcb(so);
142
143         if (unp == 0)
144                 return EINVAL;
145
146         return unp_bind(unp, nam, p);
147 }
148
149 static int
150 uipc_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
151 {
152         struct unpcb *unp = sotounpcb(so);
153
154         if (unp == 0)
155                 return EINVAL;
156         return unp_connect(so, nam, curproc);
157 }
158
159 static int
160 uipc_connect2(struct socket *so1, struct socket *so2)
161 {
162         struct unpcb *unp = sotounpcb(so1);
163
164         if (unp == 0)
165                 return EINVAL;
166
167         return unp_connect2(so1, so2);
168 }
169
170 /* control is EOPNOTSUPP */
171
172 static int
173 uipc_detach(struct socket *so)
174 {
175         struct unpcb *unp = sotounpcb(so);
176
177         if (unp == 0)
178                 return EINVAL;
179
180         unp_detach(unp);
181         return 0;
182 }
183
184 static int
185 uipc_disconnect(struct socket *so)
186 {
187         struct unpcb *unp = sotounpcb(so);
188
189         if (unp == 0)
190                 return EINVAL;
191         unp_disconnect(unp);
192         return 0;
193 }
194
195 static int
196 uipc_listen(struct socket *so, struct proc *p)
197 {
198         struct unpcb *unp = sotounpcb(so);
199
200         if (unp == 0 || unp->unp_vnode == 0)
201                 return EINVAL;
202         return unp_listen(unp, p);
203 }
204
205 static int
206 uipc_peeraddr(struct socket *so, struct sockaddr **nam)
207 {
208         struct unpcb *unp = sotounpcb(so);
209
210         if (unp == 0)
211                 return EINVAL;
212         if (unp->unp_conn && unp->unp_conn->unp_addr)
213                 *nam = dup_sockaddr((struct sockaddr *)unp->unp_conn->unp_addr,
214                                     1);
215         else {
216                 /*
217                  * XXX: It seems that this test always fails even when
218                  * connection is established.  So, this else clause is
219                  * added as workaround to return PF_LOCAL sockaddr.
220                  */
221                 *nam = dup_sockaddr((struct sockaddr *)&sun_noname, 1);
222         }
223         return 0;
224 }
225
226 static int
227 uipc_rcvd(struct socket *so, int flags)
228 {
229         struct unpcb *unp = sotounpcb(so);
230         struct socket *so2;
231         u_long newhiwat;
232
233         if (unp == 0)
234                 return EINVAL;
235         switch (so->so_type) {
236         case SOCK_DGRAM:
237                 panic("uipc_rcvd DGRAM?");
238                 /*NOTREACHED*/
239
240         case SOCK_STREAM:
241                 if (unp->unp_conn == 0)
242                         break;
243                 so2 = unp->unp_conn->unp_socket;
244                 /*
245                  * Adjust backpressure on sender
246                  * and wakeup any waiting to write.
247                  */
248                 so2->so_snd.sb_mbmax += unp->unp_mbcnt - so->so_rcv.sb_mbcnt;
249                 unp->unp_mbcnt = so->so_rcv.sb_mbcnt;
250                 newhiwat = so2->so_snd.sb_hiwat + unp->unp_cc -
251                     so->so_rcv.sb_cc;
252                 (void)chgsbsize(so2->so_cred->cr_uidinfo, &so2->so_snd.sb_hiwat,
253                     newhiwat, RLIM_INFINITY);
254                 unp->unp_cc = so->so_rcv.sb_cc;
255                 sowwakeup(so2);
256                 break;
257
258         default:
259                 panic("uipc_rcvd unknown socktype");
260         }
261         return 0;
262 }
263
264 /* pru_rcvoob is EOPNOTSUPP */
265
266 static int
267 uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
268           struct mbuf *control, struct proc *p)
269 {
270         int error = 0;
271         struct unpcb *unp = sotounpcb(so);
272         struct socket *so2;
273         u_long newhiwat;
274
275         if (unp == 0) {
276                 error = EINVAL;
277                 goto release;
278         }
279         if (flags & PRUS_OOB) {
280                 error = EOPNOTSUPP;
281                 goto release;
282         }
283
284         if (control && (error = unp_internalize(control, p)))
285                 goto release;
286
287         switch (so->so_type) {
288         case SOCK_DGRAM: 
289         {
290                 struct sockaddr *from;
291
292                 if (nam) {
293                         if (unp->unp_conn) {
294                                 error = EISCONN;
295                                 break;
296                         }
297                         error = unp_connect(so, nam, p);
298                         if (error)
299                                 break;
300                 } else {
301                         if (unp->unp_conn == 0) {
302                                 error = ENOTCONN;
303                                 break;
304                         }
305                 }
306                 so2 = unp->unp_conn->unp_socket;
307                 if (unp->unp_addr)
308                         from = (struct sockaddr *)unp->unp_addr;
309                 else
310                         from = &sun_noname;
311                 if (sbappendaddr(&so2->so_rcv, from, m, control)) {
312                         sorwakeup(so2);
313                         m = 0;
314                         control = 0;
315                 } else
316                         error = ENOBUFS;
317                 if (nam)
318                         unp_disconnect(unp);
319                 break;
320         }
321
322         case SOCK_STREAM:
323                 /* Connect if not connected yet. */
324                 /*
325                  * Note: A better implementation would complain
326                  * if not equal to the peer's address.
327                  */
328                 if ((so->so_state & SS_ISCONNECTED) == 0) {
329                         if (nam) {
330                                 error = unp_connect(so, nam, p);
331                                 if (error)
332                                         break;  /* XXX */
333                         } else {
334                                 error = ENOTCONN;
335                                 break;
336                         }
337                 }
338
339                 if (so->so_state & SS_CANTSENDMORE) {
340                         error = EPIPE;
341                         break;
342                 }
343                 if (unp->unp_conn == 0)
344                         panic("uipc_send connected but no connection?");
345                 so2 = unp->unp_conn->unp_socket;
346                 /*
347                  * Send to paired receive port, and then reduce
348                  * send buffer hiwater marks to maintain backpressure.
349                  * Wake up readers.
350                  */
351                 if (control) {
352                         if (sbappendcontrol(&so2->so_rcv, m, control))
353                                 control = 0;
354                 } else
355                         sbappend(&so2->so_rcv, m);
356                 so->so_snd.sb_mbmax -=
357                         so2->so_rcv.sb_mbcnt - unp->unp_conn->unp_mbcnt;
358                 unp->unp_conn->unp_mbcnt = so2->so_rcv.sb_mbcnt;
359                 newhiwat = so->so_snd.sb_hiwat -
360                     (so2->so_rcv.sb_cc - unp->unp_conn->unp_cc);
361                 (void)chgsbsize(so->so_cred->cr_uidinfo, &so->so_snd.sb_hiwat,
362                     newhiwat, RLIM_INFINITY);
363                 unp->unp_conn->unp_cc = so2->so_rcv.sb_cc;
364                 sorwakeup(so2);
365                 m = 0;
366                 break;
367
368         default:
369                 panic("uipc_send unknown socktype");
370         }
371
372         /*
373          * SEND_EOF is equivalent to a SEND followed by
374          * a SHUTDOWN.
375          */
376         if (flags & PRUS_EOF) {
377                 socantsendmore(so);
378                 unp_shutdown(unp);
379         }
380
381         if (control && error != 0)
382                 unp_dispose(control);
383
384 release:
385         if (control)
386                 m_freem(control);
387         if (m)
388                 m_freem(m);
389         return error;
390 }
391
392 static int
393 uipc_sense(struct socket *so, struct stat *sb)
394 {
395         struct unpcb *unp = sotounpcb(so);
396         struct socket *so2;
397
398         if (unp == 0)
399                 return EINVAL;
400         sb->st_blksize = so->so_snd.sb_hiwat;
401         if (so->so_type == SOCK_STREAM && unp->unp_conn != 0) {
402                 so2 = unp->unp_conn->unp_socket;
403                 sb->st_blksize += so2->so_rcv.sb_cc;
404         }
405         sb->st_dev = NOUDEV;
406         if (unp->unp_ino == 0)          /* make up a non-zero inode number */
407                 unp->unp_ino = (++unp_ino == 0) ? ++unp_ino : unp_ino;
408         sb->st_ino = unp->unp_ino;
409         return (0);
410 }
411
412 static int
413 uipc_shutdown(struct socket *so)
414 {
415         struct unpcb *unp = sotounpcb(so);
416
417         if (unp == 0)
418                 return EINVAL;
419         socantsendmore(so);
420         unp_shutdown(unp);
421         return 0;
422 }
423
424 static int
425 uipc_sockaddr(struct socket *so, struct sockaddr **nam)
426 {
427         struct unpcb *unp = sotounpcb(so);
428
429         if (unp == 0)
430                 return EINVAL;
431         if (unp->unp_addr)
432                 *nam = dup_sockaddr((struct sockaddr *)unp->unp_addr, 1);
433         return 0;
434 }
435
436 struct pr_usrreqs uipc_usrreqs = {
437         uipc_abort, uipc_accept, uipc_attach, uipc_bind, uipc_connect,
438         uipc_connect2, pru_control_notsupp, uipc_detach, uipc_disconnect,
439         uipc_listen, uipc_peeraddr, uipc_rcvd, pru_rcvoob_notsupp,
440         uipc_send, uipc_sense, uipc_shutdown, uipc_sockaddr,
441         sosend, soreceive, sopoll
442 };
443
444 int
445 uipc_ctloutput(so, sopt)
446         struct socket *so;
447         struct sockopt *sopt;
448 {
449         struct unpcb *unp = sotounpcb(so);
450         int error;
451
452         switch (sopt->sopt_dir) {
453         case SOPT_GET:
454                 switch (sopt->sopt_name) {
455                 case LOCAL_PEERCRED:
456                         if (unp->unp_flags & UNP_HAVEPC)
457                                 error = sooptcopyout(sopt, &unp->unp_peercred,
458                                     sizeof(unp->unp_peercred));
459                         else {
460                                 if (so->so_type == SOCK_STREAM)
461                                         error = ENOTCONN;
462                                 else
463                                         error = EINVAL;
464                         }
465                         break;
466                 default:
467                         error = EOPNOTSUPP;
468                         break;
469                 }
470                 break;
471         case SOPT_SET:
472         default:
473                 error = EOPNOTSUPP;
474                 break;
475         }
476         return (error);
477 }
478         
479 /*
480  * Both send and receive buffers are allocated PIPSIZ bytes of buffering
481  * for stream sockets, although the total for sender and receiver is
482  * actually only PIPSIZ.
483  * Datagram sockets really use the sendspace as the maximum datagram size,
484  * and don't really want to reserve the sendspace.  Their recvspace should
485  * be large enough for at least one max-size datagram plus address.
486  */
487 #ifndef PIPSIZ
488 #define PIPSIZ  8192
489 #endif
490 static u_long   unpst_sendspace = PIPSIZ;
491 static u_long   unpst_recvspace = PIPSIZ;
492 static u_long   unpdg_sendspace = 2*1024;       /* really max datagram size */
493 static u_long   unpdg_recvspace = 4*1024;
494
495 static int      unp_rights;                     /* file descriptors in flight */
496
497 SYSCTL_DECL(_net_local_stream);
498 SYSCTL_INT(_net_local_stream, OID_AUTO, sendspace, CTLFLAG_RW, 
499            &unpst_sendspace, 0, "");
500 SYSCTL_INT(_net_local_stream, OID_AUTO, recvspace, CTLFLAG_RW,
501            &unpst_recvspace, 0, "");
502 SYSCTL_DECL(_net_local_dgram);
503 SYSCTL_INT(_net_local_dgram, OID_AUTO, maxdgram, CTLFLAG_RW,
504            &unpdg_sendspace, 0, "");
505 SYSCTL_INT(_net_local_dgram, OID_AUTO, recvspace, CTLFLAG_RW,
506            &unpdg_recvspace, 0, "");
507 SYSCTL_DECL(_net_local);
508 SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0, "");
509
510 static int
511 unp_attach(so)
512         struct socket *so;
513 {
514         register struct unpcb *unp;
515         int error;
516
517         if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
518                 switch (so->so_type) {
519
520                 case SOCK_STREAM:
521                         error = soreserve(so, unpst_sendspace, unpst_recvspace);
522                         break;
523
524                 case SOCK_DGRAM:
525                         error = soreserve(so, unpdg_sendspace, unpdg_recvspace);
526                         break;
527
528                 default:
529                         panic("unp_attach");
530                 }
531                 if (error)
532                         return (error);
533         }
534         unp = zalloc(unp_zone);
535         if (unp == NULL)
536                 return (ENOBUFS);
537         bzero(unp, sizeof *unp);
538         unp->unp_gencnt = ++unp_gencnt;
539         unp_count++;
540         LIST_INIT(&unp->unp_refs);
541         unp->unp_socket = so;
542         unp->unp_rvnode = curproc->p_fd->fd_rdir;
543         LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead
544                          : &unp_shead, unp, unp_link);
545         so->so_pcb = (caddr_t)unp;
546         return (0);
547 }
548
549 static void
550 unp_detach(unp)
551         register struct unpcb *unp;
552 {
553         LIST_REMOVE(unp, unp_link);
554         unp->unp_gencnt = ++unp_gencnt;
555         --unp_count;
556         if (unp->unp_vnode) {
557                 unp->unp_vnode->v_socket = 0;
558                 vrele(unp->unp_vnode);
559                 unp->unp_vnode = 0;
560         }
561         if (unp->unp_conn)
562                 unp_disconnect(unp);
563         while (!LIST_EMPTY(&unp->unp_refs))
564                 unp_drop(LIST_FIRST(&unp->unp_refs), ECONNRESET);
565         soisdisconnected(unp->unp_socket);
566         unp->unp_socket->so_pcb = 0;
567         if (unp_rights) {
568                 /*
569                  * Normally the receive buffer is flushed later,
570                  * in sofree, but if our receive buffer holds references
571                  * to descriptors that are now garbage, we will dispose
572                  * of those descriptor references after the garbage collector
573                  * gets them (resulting in a "panic: closef: count < 0").
574                  */
575                 sorflush(unp->unp_socket);
576                 unp_gc();
577         }
578         if (unp->unp_addr)
579                 FREE(unp->unp_addr, M_SONAME);
580         zfree(unp_zone, unp);
581 }
582
583 static int
584 unp_bind(unp, nam, p)
585         struct unpcb *unp;
586         struct sockaddr *nam;
587         struct proc *p;
588 {
589         struct sockaddr_un *soun = (struct sockaddr_un *)nam;
590         register struct vnode *vp;
591         struct vattr vattr;
592         int error, namelen;
593         struct nameidata nd;
594         char buf[SOCK_MAXADDRLEN];
595
596         if (unp->unp_vnode != NULL)
597                 return (EINVAL);
598         namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path);
599         if (namelen <= 0)
600                 return EINVAL;
601         strncpy(buf, soun->sun_path, namelen);
602         buf[namelen] = 0;       /* null-terminate the string */
603         NDINIT(&nd, CREATE, NOFOLLOW | LOCKPARENT, UIO_SYSSPACE,
604             buf, p);
605 /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */
606         error = namei(&nd);
607         if (error)
608                 return (error);
609         vp = nd.ni_vp;
610         if (vp != NULL) {
611                 NDFREE(&nd, NDF_ONLY_PNBUF);
612                 if (nd.ni_dvp == vp)
613                         vrele(nd.ni_dvp);
614                 else
615                         vput(nd.ni_dvp);
616                 vrele(vp);
617                 return (EADDRINUSE);
618         }
619         VATTR_NULL(&vattr);
620         vattr.va_type = VSOCK;
621         vattr.va_mode = (ACCESSPERMS & ~p->p_fd->fd_cmask);
622         VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
623         error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
624         NDFREE(&nd, NDF_ONLY_PNBUF);
625         vput(nd.ni_dvp);
626         if (error)
627                 return (error);
628         vp = nd.ni_vp;
629         vp->v_socket = unp->unp_socket;
630         unp->unp_vnode = vp;
631         unp->unp_addr = (struct sockaddr_un *)dup_sockaddr(nam, 1);
632         VOP_UNLOCK(vp, 0, p);
633         return (0);
634 }
635
636 static int
637 unp_connect(so, nam, p)
638         struct socket *so;
639         struct sockaddr *nam;
640         struct proc *p;
641 {
642         register struct sockaddr_un *soun = (struct sockaddr_un *)nam;
643         register struct vnode *vp;
644         register struct socket *so2, *so3;
645         struct unpcb *unp, *unp2, *unp3;
646         int error, len;
647         struct nameidata nd;
648         char buf[SOCK_MAXADDRLEN];
649
650         len = nam->sa_len - offsetof(struct sockaddr_un, sun_path);
651         if (len <= 0)
652                 return EINVAL;
653         strncpy(buf, soun->sun_path, len);
654         buf[len] = 0;
655
656         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, buf, p);
657         error = namei(&nd);
658         if (error)
659                 return (error);
660         vp = nd.ni_vp;
661         NDFREE(&nd, NDF_ONLY_PNBUF);
662         if (vp->v_type != VSOCK) {
663                 error = ENOTSOCK;
664                 goto bad;
665         }
666         error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p);
667         if (error)
668                 goto bad;
669         so2 = vp->v_socket;
670         if (so2 == 0) {
671                 error = ECONNREFUSED;
672                 goto bad;
673         }
674         if (so->so_type != so2->so_type) {
675                 error = EPROTOTYPE;
676                 goto bad;
677         }
678         if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
679                 if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
680                     (so3 = sonewconn3(so2, 0, p)) == 0) {
681                         error = ECONNREFUSED;
682                         goto bad;
683                 }
684                 unp = sotounpcb(so);
685                 unp2 = sotounpcb(so2);
686                 unp3 = sotounpcb(so3);
687                 if (unp2->unp_addr)
688                         unp3->unp_addr = (struct sockaddr_un *)
689                                 dup_sockaddr((struct sockaddr *)
690                                              unp2->unp_addr, 1);
691
692                 /*
693                  * unp_peercred management:
694                  *
695                  * The connecter's (client's) credentials are copied
696                  * from its process structure at the time of connect()
697                  * (which is now).
698                  */
699                 cru2x(p->p_ucred, &unp3->unp_peercred);
700                 unp3->unp_flags |= UNP_HAVEPC;
701                 /*
702                  * The receiver's (server's) credentials are copied
703                  * from the unp_peercred member of socket on which the
704                  * former called listen(); unp_listen() cached that
705                  * process's credentials at that time so we can use
706                  * them now.
707                  */
708                 KASSERT(unp2->unp_flags & UNP_HAVEPCCACHED,
709                     ("unp_connect: listener without cached peercred"));
710                 memcpy(&unp->unp_peercred, &unp2->unp_peercred,
711                     sizeof(unp->unp_peercred));
712                 unp->unp_flags |= UNP_HAVEPC;
713
714                 so2 = so3;
715         }
716         error = unp_connect2(so, so2);
717 bad:
718         vput(vp);
719         return (error);
720 }
721
722 int
723 unp_connect2(so, so2)
724         register struct socket *so;
725         register struct socket *so2;
726 {
727         register struct unpcb *unp = sotounpcb(so);
728         register struct unpcb *unp2;
729
730         if (so2->so_type != so->so_type)
731                 return (EPROTOTYPE);
732         unp2 = sotounpcb(so2);
733         unp->unp_conn = unp2;
734         switch (so->so_type) {
735
736         case SOCK_DGRAM:
737                 LIST_INSERT_HEAD(&unp2->unp_refs, unp, unp_reflink);
738                 soisconnected(so);
739                 break;
740
741         case SOCK_STREAM:
742                 unp2->unp_conn = unp;
743                 soisconnected(so);
744                 soisconnected(so2);
745                 break;
746
747         default:
748                 panic("unp_connect2");
749         }
750         return (0);
751 }
752
753 static void
754 unp_disconnect(unp)
755         struct unpcb *unp;
756 {
757         register struct unpcb *unp2 = unp->unp_conn;
758
759         if (unp2 == 0)
760                 return;
761         unp->unp_conn = 0;
762         switch (unp->unp_socket->so_type) {
763
764         case SOCK_DGRAM:
765                 LIST_REMOVE(unp, unp_reflink);
766                 unp->unp_socket->so_state &= ~SS_ISCONNECTED;
767                 break;
768
769         case SOCK_STREAM:
770                 soisdisconnected(unp->unp_socket);
771                 unp2->unp_conn = 0;
772                 soisdisconnected(unp2->unp_socket);
773                 break;
774         }
775 }
776
777 #ifdef notdef
778 void
779 unp_abort(unp)
780         struct unpcb *unp;
781 {
782
783         unp_detach(unp);
784 }
785 #endif
786
787 static int
788 prison_unpcb(struct proc *p, struct unpcb *unp)
789 {
790         if (!p->p_prison)
791                 return (0);
792         if (p->p_fd->fd_rdir == unp->unp_rvnode)
793                 return (0);
794         return (1);
795 }
796
797 static int
798 unp_pcblist(SYSCTL_HANDLER_ARGS)
799 {
800         int error, i, n;
801         struct unpcb *unp, **unp_list;
802         unp_gen_t gencnt;
803         struct xunpgen xug;
804         struct unp_head *head;
805
806         head = ((intptr_t)arg1 == SOCK_DGRAM ? &unp_dhead : &unp_shead);
807
808         /*
809          * The process of preparing the PCB list is too time-consuming and
810          * resource-intensive to repeat twice on every request.
811          */
812         if (req->oldptr == 0) {
813                 n = unp_count;
814                 req->oldidx = 2 * (sizeof xug)
815                         + (n + n/8) * sizeof(struct xunpcb);
816                 return 0;
817         }
818
819         if (req->newptr != 0)
820                 return EPERM;
821
822         /*
823          * OK, now we're committed to doing something.
824          */
825         gencnt = unp_gencnt;
826         n = unp_count;
827
828         xug.xug_len = sizeof xug;
829         xug.xug_count = n;
830         xug.xug_gen = gencnt;
831         xug.xug_sogen = so_gencnt;
832         error = SYSCTL_OUT(req, &xug, sizeof xug);
833         if (error)
834                 return error;
835
836         unp_list = malloc(n * sizeof *unp_list, M_TEMP, M_WAITOK);
837         if (unp_list == 0)
838                 return ENOMEM;
839         
840         for (unp = LIST_FIRST(head), i = 0; unp && i < n;
841              unp = LIST_NEXT(unp, unp_link)) {
842                 if (unp->unp_gencnt <= gencnt && !prison_unpcb(req->p, unp))
843                         unp_list[i++] = unp;
844         }
845         n = i;                  /* in case we lost some during malloc */
846
847         error = 0;
848         for (i = 0; i < n; i++) {
849                 unp = unp_list[i];
850                 if (unp->unp_gencnt <= gencnt) {
851                         struct xunpcb xu;
852                         xu.xu_len = sizeof xu;
853                         xu.xu_unpp = unp;
854                         /*
855                          * XXX - need more locking here to protect against
856                          * connect/disconnect races for SMP.
857                          */
858                         if (unp->unp_addr)
859                                 bcopy(unp->unp_addr, &xu.xu_addr, 
860                                       unp->unp_addr->sun_len);
861                         if (unp->unp_conn && unp->unp_conn->unp_addr)
862                                 bcopy(unp->unp_conn->unp_addr,
863                                       &xu.xu_caddr,
864                                       unp->unp_conn->unp_addr->sun_len);
865                         bcopy(unp, &xu.xu_unp, sizeof *unp);
866                         sotoxsocket(unp->unp_socket, &xu.xu_socket);
867                         error = SYSCTL_OUT(req, &xu, sizeof xu);
868                 }
869         }
870         if (!error) {
871                 /*
872                  * Give the user an updated idea of our state.
873                  * If the generation differs from what we told
874                  * her before, she knows that something happened
875                  * while we were processing this request, and it
876                  * might be necessary to retry.
877                  */
878                 xug.xug_gen = unp_gencnt;
879                 xug.xug_sogen = so_gencnt;
880                 xug.xug_count = unp_count;
881                 error = SYSCTL_OUT(req, &xug, sizeof xug);
882         }
883         free(unp_list, M_TEMP);
884         return error;
885 }
886
887 SYSCTL_PROC(_net_local_dgram, OID_AUTO, pcblist, CTLFLAG_RD, 
888             (caddr_t)(long)SOCK_DGRAM, 0, unp_pcblist, "S,xunpcb",
889             "List of active local datagram sockets");
890 SYSCTL_PROC(_net_local_stream, OID_AUTO, pcblist, CTLFLAG_RD, 
891             (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist, "S,xunpcb",
892             "List of active local stream sockets");
893
894 static void
895 unp_shutdown(unp)
896         struct unpcb *unp;
897 {
898         struct socket *so;
899
900         if (unp->unp_socket->so_type == SOCK_STREAM && unp->unp_conn &&
901             (so = unp->unp_conn->unp_socket))
902                 socantrcvmore(so);
903 }
904
905 static void
906 unp_drop(unp, errno)
907         struct unpcb *unp;
908         int errno;
909 {
910         struct socket *so = unp->unp_socket;
911
912         so->so_error = errno;
913         unp_disconnect(unp);
914 }
915
916 #ifdef notdef
917 void
918 unp_drain()
919 {
920
921 }
922 #endif
923
924 int
925 unp_externalize(rights)
926         struct mbuf *rights;
927 {
928         struct proc *p = curproc;               /* XXX */
929         register int i;
930         register struct cmsghdr *cm = mtod(rights, struct cmsghdr *);
931         register int *fdp;
932         register struct file **rp;
933         register struct file *fp;
934         int newfds = (cm->cmsg_len - (CMSG_DATA(cm) - (u_char *)cm))
935                 / sizeof (struct file *);
936         int f;
937
938         /*
939          * if the new FD's will not fit, then we free them all
940          */
941         if (!fdavail(p, newfds)) {
942                 rp = (struct file **)CMSG_DATA(cm);
943                 for (i = 0; i < newfds; i++) {
944                         fp = *rp;
945                         /*
946                          * zero the pointer before calling unp_discard,
947                          * since it may end up in unp_gc()..
948                          */
949                         *rp++ = 0;
950                         unp_discard(fp);
951                 }
952                 return (EMSGSIZE);
953         }
954         /*
955          * now change each pointer to an fd in the global table to 
956          * an integer that is the index to the local fd table entry
957          * that we set up to point to the global one we are transferring.
958          * If sizeof (struct file *) is bigger than or equal to sizeof int,
959          * then do it in forward order. In that case, an integer will
960          * always come in the same place or before its corresponding
961          * struct file pointer.
962          * If sizeof (struct file *) is smaller than sizeof int, then
963          * do it in reverse order.
964          */
965         if (sizeof (struct file *) >= sizeof (int)) {
966                 fdp = (int *)(cm + 1);
967                 rp = (struct file **)CMSG_DATA(cm);
968                 for (i = 0; i < newfds; i++) {
969                         if (fdalloc(p, 0, &f))
970                                 panic("unp_externalize");
971                         fp = *rp++;
972                         p->p_fd->fd_ofiles[f] = fp;
973                         fp->f_msgcount--;
974                         unp_rights--;
975                         *fdp++ = f;
976                 }
977         } else {
978                 fdp = (int *)(cm + 1) + newfds - 1;
979                 rp = (struct file **)CMSG_DATA(cm) + newfds - 1;
980                 for (i = 0; i < newfds; i++) {
981                         if (fdalloc(p, 0, &f))
982                                 panic("unp_externalize");
983                         fp = *rp--;
984                         p->p_fd->fd_ofiles[f] = fp;
985                         fp->f_msgcount--;
986                         unp_rights--;
987                         *fdp-- = f;
988                 }
989         }
990
991         /*
992          * Adjust length, in case sizeof(struct file *) and sizeof(int)
993          * differs.
994          */
995         cm->cmsg_len = CMSG_LEN(newfds * sizeof(int));
996         rights->m_len = cm->cmsg_len;
997         return (0);
998 }
999
1000 void
1001 unp_init(void)
1002 {
1003         unp_zone = zinit("unpcb", sizeof(struct unpcb), nmbclusters, 0, 0);
1004         if (unp_zone == 0)
1005                 panic("unp_init");
1006         LIST_INIT(&unp_dhead);
1007         LIST_INIT(&unp_shead);
1008 }
1009
1010 #ifndef MIN
1011 #define MIN(a,b) (((a)<(b))?(a):(b))
1012 #endif
1013
1014 static int
1015 unp_internalize(control, p)
1016         struct mbuf *control;
1017         struct proc *p;
1018 {
1019         struct filedesc *fdescp = p->p_fd;
1020         register struct cmsghdr *cm = mtod(control, struct cmsghdr *);
1021         register struct file **rp;
1022         register struct file *fp;
1023         register int i, fd, *fdp;
1024         register struct cmsgcred *cmcred;
1025         int oldfds;
1026         u_int newlen;
1027
1028         if ((cm->cmsg_type != SCM_RIGHTS && cm->cmsg_type != SCM_CREDS) ||
1029             cm->cmsg_level != SOL_SOCKET || cm->cmsg_len != control->m_len)
1030                 return (EINVAL);
1031
1032         /*
1033          * Fill in credential information.
1034          */
1035         if (cm->cmsg_type == SCM_CREDS) {
1036                 cmcred = (struct cmsgcred *)(cm + 1);
1037                 cmcred->cmcred_pid = p->p_pid;
1038                 cmcred->cmcred_uid = p->p_cred->p_ruid;
1039                 cmcred->cmcred_gid = p->p_cred->p_rgid;
1040                 cmcred->cmcred_euid = p->p_ucred->cr_uid;
1041                 cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups,
1042                                                         CMGROUP_MAX);
1043                 for (i = 0; i < cmcred->cmcred_ngroups; i++)
1044                         cmcred->cmcred_groups[i] = p->p_ucred->cr_groups[i];
1045                 return(0);
1046         }
1047
1048         oldfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int);
1049         /*
1050          * check that all the FDs passed in refer to legal OPEN files
1051          * If not, reject the entire operation.
1052          */
1053         fdp = (int *)(cm + 1);
1054         for (i = 0; i < oldfds; i++) {
1055                 fd = *fdp++;
1056                 if ((unsigned)fd >= fdescp->fd_nfiles ||
1057                     fdescp->fd_ofiles[fd] == NULL)
1058                         return (EBADF);
1059                 if (fdescp->fd_ofiles[fd]->f_type == DTYPE_KQUEUE)
1060                         return (EOPNOTSUPP);
1061         }
1062         /*
1063          * Now replace the integer FDs with pointers to
1064          * the associated global file table entry..
1065          * Allocate a bigger buffer as necessary. But if an cluster is not
1066          * enough, return E2BIG.
1067          */
1068         newlen = CMSG_LEN(oldfds * sizeof(struct file *));
1069         if (newlen > MCLBYTES)
1070                 return (E2BIG);
1071         if (newlen - control->m_len > M_TRAILINGSPACE(control)) {
1072                 if (control->m_flags & M_EXT)
1073                         return (E2BIG);
1074                 MCLGET(control, M_WAIT);
1075                 if ((control->m_flags & M_EXT) == 0)
1076                         return (ENOBUFS);
1077
1078                 /* copy the data to the cluster */
1079                 memcpy(mtod(control, char *), cm, cm->cmsg_len);
1080                 cm = mtod(control, struct cmsghdr *);
1081         }
1082
1083         /*
1084          * Adjust length, in case sizeof(struct file *) and sizeof(int)
1085          * differs.
1086          */
1087         control->m_len = cm->cmsg_len = newlen;
1088
1089         /*
1090          * Transform the file descriptors into struct file pointers.
1091          * If sizeof (struct file *) is bigger than or equal to sizeof int,
1092          * then do it in reverse order so that the int won't get until
1093          * we're done.
1094          * If sizeof (struct file *) is smaller than sizeof int, then
1095          * do it in forward order.
1096          */
1097         if (sizeof (struct file *) >= sizeof (int)) {
1098                 fdp = (int *)(cm + 1) + oldfds - 1;
1099                 rp = (struct file **)CMSG_DATA(cm) + oldfds - 1;
1100                 for (i = 0; i < oldfds; i++) {
1101                         fp = fdescp->fd_ofiles[*fdp--];
1102                         *rp-- = fp;
1103                         fp->f_count++;
1104                         fp->f_msgcount++;
1105                         unp_rights++;
1106                 }
1107         } else {
1108                 fdp = (int *)(cm + 1);
1109                 rp = (struct file **)CMSG_DATA(cm);
1110                 for (i = 0; i < oldfds; i++) {
1111                         fp = fdescp->fd_ofiles[*fdp++];
1112                         *rp++ = fp;
1113                         fp->f_count++;
1114                         fp->f_msgcount++;
1115                         unp_rights++;
1116                 }
1117         }
1118         return (0);
1119 }
1120
1121 static int      unp_defer, unp_gcing;
1122
1123 static void
1124 unp_gc()
1125 {
1126         register struct file *fp, *nextfp;
1127         register struct socket *so;
1128         struct file **extra_ref, **fpp;
1129         int nunref, i;
1130
1131         if (unp_gcing)
1132                 return;
1133         unp_gcing = 1;
1134         unp_defer = 0;
1135         /* 
1136          * before going through all this, set all FDs to 
1137          * be NOT defered and NOT externally accessible
1138          */
1139         LIST_FOREACH(fp, &filehead, f_list)
1140                 fp->f_flag &= ~(FMARK|FDEFER);
1141         do {
1142                 LIST_FOREACH(fp, &filehead, f_list) {
1143                         /*
1144                          * If the file is not open, skip it
1145                          */
1146                         if (fp->f_count == 0)
1147                                 continue;
1148                         /*
1149                          * If we already marked it as 'defer'  in a
1150                          * previous pass, then try process it this time
1151                          * and un-mark it
1152                          */
1153                         if (fp->f_flag & FDEFER) {
1154                                 fp->f_flag &= ~FDEFER;
1155                                 unp_defer--;
1156                         } else {
1157                                 /*
1158                                  * if it's not defered, then check if it's
1159                                  * already marked.. if so skip it
1160                                  */
1161                                 if (fp->f_flag & FMARK)
1162                                         continue;
1163                                 /* 
1164                                  * If all references are from messages
1165                                  * in transit, then skip it. it's not 
1166                                  * externally accessible.
1167                                  */ 
1168                                 if (fp->f_count == fp->f_msgcount)
1169                                         continue;
1170                                 /* 
1171                                  * If it got this far then it must be
1172                                  * externally accessible.
1173                                  */
1174                                 fp->f_flag |= FMARK;
1175                         }
1176                         /*
1177                          * either it was defered, or it is externally 
1178                          * accessible and not already marked so.
1179                          * Now check if it is possibly one of OUR sockets.
1180                          */ 
1181                         if (fp->f_type != DTYPE_SOCKET ||
1182                             (so = (struct socket *)fp->f_data) == 0)
1183                                 continue;
1184                         if (so->so_proto->pr_domain != &localdomain ||
1185                             (so->so_proto->pr_flags&PR_RIGHTS) == 0)
1186                                 continue;
1187 #ifdef notdef
1188                         if (so->so_rcv.sb_flags & SB_LOCK) {
1189                                 /*
1190                                  * This is problematical; it's not clear
1191                                  * we need to wait for the sockbuf to be
1192                                  * unlocked (on a uniprocessor, at least),
1193                                  * and it's also not clear what to do
1194                                  * if sbwait returns an error due to receipt
1195                                  * of a signal.  If sbwait does return
1196                                  * an error, we'll go into an infinite
1197                                  * loop.  Delete all of this for now.
1198                                  */
1199                                 (void) sbwait(&so->so_rcv);
1200                                 goto restart;
1201                         }
1202 #endif
1203                         /*
1204                          * So, Ok, it's one of our sockets and it IS externally
1205                          * accessible (or was defered). Now we look
1206                          * to see if we hold any file descriptors in its
1207                          * message buffers. Follow those links and mark them 
1208                          * as accessible too.
1209                          */
1210                         unp_scan(so->so_rcv.sb_mb, unp_mark);
1211                 }
1212         } while (unp_defer);
1213         /*
1214          * We grab an extra reference to each of the file table entries
1215          * that are not otherwise accessible and then free the rights
1216          * that are stored in messages on them.
1217          *
1218          * The bug in the orginal code is a little tricky, so I'll describe
1219          * what's wrong with it here.
1220          *
1221          * It is incorrect to simply unp_discard each entry for f_msgcount
1222          * times -- consider the case of sockets A and B that contain
1223          * references to each other.  On a last close of some other socket,
1224          * we trigger a gc since the number of outstanding rights (unp_rights)
1225          * is non-zero.  If during the sweep phase the gc code un_discards,
1226          * we end up doing a (full) closef on the descriptor.  A closef on A
1227          * results in the following chain.  Closef calls soo_close, which
1228          * calls soclose.   Soclose calls first (through the switch
1229          * uipc_usrreq) unp_detach, which re-invokes unp_gc.  Unp_gc simply
1230          * returns because the previous instance had set unp_gcing, and
1231          * we return all the way back to soclose, which marks the socket
1232          * with SS_NOFDREF, and then calls sofree.  Sofree calls sorflush
1233          * to free up the rights that are queued in messages on the socket A,
1234          * i.e., the reference on B.  The sorflush calls via the dom_dispose
1235          * switch unp_dispose, which unp_scans with unp_discard.  This second
1236          * instance of unp_discard just calls closef on B.
1237          *
1238          * Well, a similar chain occurs on B, resulting in a sorflush on B,
1239          * which results in another closef on A.  Unfortunately, A is already
1240          * being closed, and the descriptor has already been marked with
1241          * SS_NOFDREF, and soclose panics at this point.
1242          *
1243          * Here, we first take an extra reference to each inaccessible
1244          * descriptor.  Then, we call sorflush ourself, since we know
1245          * it is a Unix domain socket anyhow.  After we destroy all the
1246          * rights carried in messages, we do a last closef to get rid
1247          * of our extra reference.  This is the last close, and the
1248          * unp_detach etc will shut down the socket.
1249          *
1250          * 91/09/19, bsy@cs.cmu.edu
1251          */
1252         extra_ref = malloc(nfiles * sizeof(struct file *), M_FILE, M_WAITOK);
1253         for (nunref = 0, fp = LIST_FIRST(&filehead), fpp = extra_ref; fp != 0;
1254             fp = nextfp) {
1255                 nextfp = LIST_NEXT(fp, f_list);
1256                 /* 
1257                  * If it's not open, skip it
1258                  */
1259                 if (fp->f_count == 0)
1260                         continue;
1261                 /* 
1262                  * If all refs are from msgs, and it's not marked accessible
1263                  * then it must be referenced from some unreachable cycle
1264                  * of (shut-down) FDs, so include it in our
1265                  * list of FDs to remove
1266                  */
1267                 if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
1268                         *fpp++ = fp;
1269                         nunref++;
1270                         fp->f_count++;
1271                 }
1272         }
1273         /* 
1274          * for each FD on our hit list, do the following two things
1275          */
1276         for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
1277                 struct file *tfp = *fpp;
1278                 if (tfp->f_type == DTYPE_SOCKET && tfp->f_data != NULL)
1279                         sorflush((struct socket *)(tfp->f_data));
1280         }
1281         for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
1282                 closef(*fpp, (struct proc *) NULL);
1283         free((caddr_t)extra_ref, M_FILE);
1284         unp_gcing = 0;
1285 }
1286
1287 void
1288 unp_dispose(m)
1289         struct mbuf *m;
1290 {
1291
1292         if (m)
1293                 unp_scan(m, unp_discard);
1294 }
1295
1296 static int
1297 unp_listen(unp, p)
1298         struct unpcb *unp;
1299         struct proc *p;
1300 {
1301
1302         cru2x(p->p_ucred, &unp->unp_peercred);
1303         unp->unp_flags |= UNP_HAVEPCCACHED;
1304         return (0);
1305 }
1306
1307 static void
1308 unp_scan(m0, op)
1309         register struct mbuf *m0;
1310         void (*op) __P((struct file *));
1311 {
1312         register struct mbuf *m;
1313         register struct file **rp;
1314         register struct cmsghdr *cm;
1315         register int i;
1316         int qfds;
1317
1318         while (m0) {
1319                 for (m = m0; m; m = m->m_next)
1320                         if (m->m_type == MT_CONTROL &&
1321                             m->m_len >= sizeof(*cm)) {
1322                                 cm = mtod(m, struct cmsghdr *);
1323                                 if (cm->cmsg_level != SOL_SOCKET ||
1324                                     cm->cmsg_type != SCM_RIGHTS)
1325                                         continue;
1326                                 qfds = (cm->cmsg_len -
1327                                         (CMSG_DATA(cm) - (u_char *)cm))
1328                                                 / sizeof (struct file *);
1329                                 rp = (struct file **)CMSG_DATA(cm);
1330                                 for (i = 0; i < qfds; i++)
1331                                         (*op)(*rp++);
1332                                 break;          /* XXX, but saves time */
1333                         }
1334                 m0 = m0->m_act;
1335         }
1336 }
1337
1338 static void
1339 unp_mark(fp)
1340         struct file *fp;
1341 {
1342
1343         if (fp->f_flag & FMARK)
1344                 return;
1345         unp_defer++;
1346         fp->f_flag |= (FMARK|FDEFER);
1347 }
1348
1349 static void
1350 unp_discard(fp)
1351         struct file *fp;
1352 {
1353
1354         fp->f_msgcount--;
1355         unp_rights--;
1356         (void) closef(fp, (struct proc *)NULL);
1357 }