]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/uipc_socket2.c
Add the tp->t_refcnt validity check back. There are still some race
[FreeBSD/FreeBSD.git] / sys / kern / uipc_socket2.c
1 /*-
2  * Copyright (c) 1982, 1986, 1988, 1990, 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  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *      @(#)uipc_socket2.c      8.1 (Berkeley) 6/10/93
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include "opt_param.h"
36
37 #include <sys/param.h>
38 #include <sys/domain.h>
39 #include <sys/lock.h>
40 #include <sys/malloc.h>
41 #include <sys/mbuf.h>
42 #include <sys/mutex.h>
43 #include <sys/proc.h>
44 #include <sys/protosw.h>
45 #include <sys/resourcevar.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
48 #include <sys/stat.h>
49
50 /*
51  * Primitive routines for operating on sockets.
52  */
53
54 /*
55  * Procedures to manipulate state flags of socket
56  * and do appropriate wakeups.  Normal sequence from the
57  * active (originating) side is that soisconnecting() is
58  * called during processing of connect() call,
59  * resulting in an eventual call to soisconnected() if/when the
60  * connection is established.  When the connection is torn down
61  * soisdisconnecting() is called during processing of disconnect() call,
62  * and soisdisconnected() is called when the connection to the peer
63  * is totally severed.  The semantics of these routines are such that
64  * connectionless protocols can call soisconnected() and soisdisconnected()
65  * only, bypassing the in-progress calls when setting up a ``connection''
66  * takes no time.
67  *
68  * From the passive side, a socket is created with
69  * two queues of sockets: so_incomp for connections in progress
70  * and so_comp for connections already made and awaiting user acceptance.
71  * As a protocol is preparing incoming connections, it creates a socket
72  * structure queued on so_incomp by calling sonewconn().  When the connection
73  * is established, soisconnected() is called, and transfers the
74  * socket structure to so_comp, making it available to accept().
75  *
76  * If a socket is closed with sockets on either
77  * so_incomp or so_comp, these sockets are dropped.
78  *
79  * If higher level protocols are implemented in
80  * the kernel, the wakeups done here will sometimes
81  * cause software-interrupt process scheduling.
82  */
83
84 void
85 soisconnecting(so)
86         register struct socket *so;
87 {
88
89         SOCK_LOCK(so);
90         so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
91         so->so_state |= SS_ISCONNECTING;
92         SOCK_UNLOCK(so);
93 }
94
95 void
96 soisconnected(so)
97         struct socket *so;
98 {
99         struct socket *head;
100
101         ACCEPT_LOCK();
102         SOCK_LOCK(so);
103         so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
104         so->so_state |= SS_ISCONNECTED;
105         head = so->so_head;
106         if (head != NULL && (so->so_qstate & SQ_INCOMP)) {
107                 if ((so->so_options & SO_ACCEPTFILTER) == 0) {
108                         SOCK_UNLOCK(so);
109                         TAILQ_REMOVE(&head->so_incomp, so, so_list);
110                         head->so_incqlen--;
111                         so->so_qstate &= ~SQ_INCOMP;
112                         TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
113                         head->so_qlen++;
114                         so->so_qstate |= SQ_COMP;
115                         ACCEPT_UNLOCK();
116                         sorwakeup(head);
117                         wakeup_one(&head->so_timeo);
118                 } else {
119                         ACCEPT_UNLOCK();
120                         so->so_upcall =
121                             head->so_accf->so_accept_filter->accf_callback;
122                         so->so_upcallarg = head->so_accf->so_accept_filter_arg;
123                         so->so_rcv.sb_flags |= SB_UPCALL;
124                         so->so_options &= ~SO_ACCEPTFILTER;
125                         SOCK_UNLOCK(so);
126                         so->so_upcall(so, so->so_upcallarg, M_DONTWAIT);
127                 }
128                 return;
129         }
130         SOCK_UNLOCK(so);
131         ACCEPT_UNLOCK();
132         wakeup(&so->so_timeo);
133         sorwakeup(so);
134         sowwakeup(so);
135 }
136
137 void
138 soisdisconnecting(so)
139         register struct socket *so;
140 {
141
142         /*
143          * Note: This code assumes that SOCK_LOCK(so) and
144          * SOCKBUF_LOCK(&so->so_rcv) are the same.
145          */
146         SOCKBUF_LOCK(&so->so_rcv);
147         so->so_state &= ~SS_ISCONNECTING;
148         so->so_state |= SS_ISDISCONNECTING;
149         so->so_rcv.sb_state |= SBS_CANTRCVMORE;
150         sorwakeup_locked(so);
151         SOCKBUF_LOCK(&so->so_snd);
152         so->so_snd.sb_state |= SBS_CANTSENDMORE;
153         sowwakeup_locked(so);
154         wakeup(&so->so_timeo);
155 }
156
157 void
158 soisdisconnected(so)
159         register struct socket *so;
160 {
161
162         /*
163          * Note: This code assumes that SOCK_LOCK(so) and
164          * SOCKBUF_LOCK(&so->so_rcv) are the same.
165          */
166         SOCKBUF_LOCK(&so->so_rcv);
167         so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
168         so->so_state |= SS_ISDISCONNECTED;
169         so->so_rcv.sb_state |= SBS_CANTRCVMORE;
170         sorwakeup_locked(so);
171         SOCKBUF_LOCK(&so->so_snd);
172         so->so_snd.sb_state |= SBS_CANTSENDMORE;
173         sbdrop_locked(&so->so_snd, so->so_snd.sb_cc);
174         sowwakeup_locked(so);
175         wakeup(&so->so_timeo);
176 }
177
178 /*
179  * Create a "control" mbuf containing the specified data
180  * with the specified type for presentation on a socket buffer.
181  */
182 struct mbuf *
183 sbcreatecontrol(p, size, type, level)
184         caddr_t p;
185         register int size;
186         int type, level;
187 {
188         register struct cmsghdr *cp;
189         struct mbuf *m;
190
191         if (CMSG_SPACE((u_int)size) > MCLBYTES)
192                 return ((struct mbuf *) NULL);
193         if (CMSG_SPACE((u_int)size) > MLEN)
194                 m = m_getcl(M_DONTWAIT, MT_CONTROL, 0);
195         else
196                 m = m_get(M_DONTWAIT, MT_CONTROL);
197         if (m == NULL)
198                 return ((struct mbuf *) NULL);
199         cp = mtod(m, struct cmsghdr *);
200         m->m_len = 0;
201         KASSERT(CMSG_SPACE((u_int)size) <= M_TRAILINGSPACE(m),
202             ("sbcreatecontrol: short mbuf"));
203         if (p != NULL)
204                 (void)memcpy(CMSG_DATA(cp), p, size);
205         m->m_len = CMSG_SPACE(size);
206         cp->cmsg_len = CMSG_LEN(size);
207         cp->cmsg_level = level;
208         cp->cmsg_type = type;
209         return (m);
210 }
211
212 /*
213  * Some routines that return EOPNOTSUPP for entry points that are not
214  * supported by a protocol.  Fill in as needed.
215  */
216 int
217 pru_accept_notsupp(struct socket *so, struct sockaddr **nam)
218 {
219         return EOPNOTSUPP;
220 }
221
222 int
223 pru_attach_notsupp(struct socket *so, int proto, struct thread *td)
224 {
225         return EOPNOTSUPP;
226 }
227
228 int
229 pru_bind_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
230 {
231         return EOPNOTSUPP;
232 }
233
234 int
235 pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
236 {
237         return EOPNOTSUPP;
238 }
239
240 int
241 pru_connect2_notsupp(struct socket *so1, struct socket *so2)
242 {
243         return EOPNOTSUPP;
244 }
245
246 int
247 pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
248         struct ifnet *ifp, struct thread *td)
249 {
250         return EOPNOTSUPP;
251 }
252
253 int
254 pru_disconnect_notsupp(struct socket *so)
255 {
256         return EOPNOTSUPP;
257 }
258
259 int
260 pru_listen_notsupp(struct socket *so, int backlog, struct thread *td)
261 {
262         return EOPNOTSUPP;
263 }
264
265 int
266 pru_peeraddr_notsupp(struct socket *so, struct sockaddr **nam)
267 {
268         return EOPNOTSUPP;
269 }
270
271 int
272 pru_rcvd_notsupp(struct socket *so, int flags)
273 {
274         return EOPNOTSUPP;
275 }
276
277 int
278 pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags)
279 {
280         return EOPNOTSUPP;
281 }
282
283 int
284 pru_send_notsupp(struct socket *so, int flags, struct mbuf *m,
285         struct sockaddr *addr, struct mbuf *control, struct thread *td)
286 {
287         return EOPNOTSUPP;
288 }
289
290 /*
291  * This isn't really a ``null'' operation, but it's the default one
292  * and doesn't do anything destructive.
293  */
294 int
295 pru_sense_null(struct socket *so, struct stat *sb)
296 {
297         sb->st_blksize = so->so_snd.sb_hiwat;
298         return 0;
299 }
300
301 int
302 pru_shutdown_notsupp(struct socket *so)
303 {
304         return EOPNOTSUPP;
305 }
306
307 int
308 pru_sockaddr_notsupp(struct socket *so, struct sockaddr **nam)
309 {
310         return EOPNOTSUPP;
311 }
312
313 int
314 pru_sosend_notsupp(struct socket *so, struct sockaddr *addr, struct uio *uio,
315         struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
316 {
317         return EOPNOTSUPP;
318 }
319
320 int
321 pru_soreceive_notsupp(struct socket *so, struct sockaddr **paddr,
322         struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
323         int *flagsp)
324 {
325         return EOPNOTSUPP;
326 }
327
328 int
329 pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred,
330         struct thread *td)
331 {
332         return EOPNOTSUPP;
333 }
334
335 /*
336  * Make a copy of a sockaddr in a malloced buffer of type M_SONAME.
337  */
338 struct sockaddr *
339 sodupsockaddr(const struct sockaddr *sa, int mflags)
340 {
341         struct sockaddr *sa2;
342
343         sa2 = malloc(sa->sa_len, M_SONAME, mflags);
344         if (sa2)
345                 bcopy(sa, sa2, sa->sa_len);
346         return sa2;
347 }
348
349 /*
350  * Create an external-format (``xsocket'') structure using the information
351  * in the kernel-format socket structure pointed to by so.  This is done
352  * to reduce the spew of irrelevant information over this interface,
353  * to isolate user code from changes in the kernel structure, and
354  * potentially to provide information-hiding if we decide that
355  * some of this information should be hidden from users.
356  */
357 void
358 sotoxsocket(struct socket *so, struct xsocket *xso)
359 {
360         xso->xso_len = sizeof *xso;
361         xso->xso_so = so;
362         xso->so_type = so->so_type;
363         xso->so_options = so->so_options;
364         xso->so_linger = so->so_linger;
365         xso->so_state = so->so_state;
366         xso->so_pcb = so->so_pcb;
367         xso->xso_protocol = so->so_proto->pr_protocol;
368         xso->xso_family = so->so_proto->pr_domain->dom_family;
369         xso->so_qlen = so->so_qlen;
370         xso->so_incqlen = so->so_incqlen;
371         xso->so_qlimit = so->so_qlimit;
372         xso->so_timeo = so->so_timeo;
373         xso->so_error = so->so_error;
374         xso->so_pgid = so->so_sigio ? so->so_sigio->sio_pgid : 0;
375         xso->so_oobmark = so->so_oobmark;
376         sbtoxsockbuf(&so->so_snd, &xso->so_snd);
377         sbtoxsockbuf(&so->so_rcv, &xso->so_rcv);
378         xso->so_uid = so->so_cred->cr_uid;
379 }
380
381 /*
382  * This does the same for sockbufs.  Note that the xsockbuf structure,
383  * since it is always embedded in a socket, does not include a self
384  * pointer nor a length.  We make this entry point public in case
385  * some other mechanism needs it.
386  */
387 void
388 sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb)
389 {
390         xsb->sb_cc = sb->sb_cc;
391         xsb->sb_hiwat = sb->sb_hiwat;
392         xsb->sb_mbcnt = sb->sb_mbcnt;
393         xsb->sb_mbmax = sb->sb_mbmax;
394         xsb->sb_lowat = sb->sb_lowat;
395         xsb->sb_flags = sb->sb_flags;
396         xsb->sb_timeo = sb->sb_timeo;
397 }