uipc_socket.c revision 1.16 1 /* $NetBSD: uipc_socket.c,v 1.16 1994/06/29 06:33:37 cgd Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1988, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
36 */
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/proc.h>
41 #include <sys/file.h>
42 #include <sys/malloc.h>
43 #include <sys/mbuf.h>
44 #include <sys/domain.h>
45 #include <sys/kernel.h>
46 #include <sys/protosw.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/resourcevar.h>
50
51 /*
52 * Socket operation routines.
53 * These routines are called by the routines in
54 * sys_socket.c or from a system process, and
55 * implement the semantics of socket operations by
56 * switching out to the protocol specific routines.
57 */
58 /*ARGSUSED*/
59 int
60 socreate(dom, aso, type, proto)
61 int dom;
62 struct socket **aso;
63 register int type;
64 int proto;
65 {
66 struct proc *p = curproc; /* XXX */
67 register struct protosw *prp;
68 register struct socket *so;
69 register int error;
70
71 if (proto)
72 prp = pffindproto(dom, proto, type);
73 else
74 prp = pffindtype(dom, type);
75 if (prp == 0 || prp->pr_usrreq == 0)
76 return (EPROTONOSUPPORT);
77 if (prp->pr_type != type)
78 return (EPROTOTYPE);
79 MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT);
80 bzero((caddr_t)so, sizeof(*so));
81 so->so_type = type;
82 if (p->p_ucred->cr_uid == 0)
83 so->so_state = SS_PRIV;
84 so->so_proto = prp;
85 error =
86 (*prp->pr_usrreq)(so, PRU_ATTACH,
87 (struct mbuf *)0, (struct mbuf *)proto, (struct mbuf *)0);
88 if (error) {
89 so->so_state |= SS_NOFDREF;
90 sofree(so);
91 return (error);
92 }
93 #ifdef COMPAT_SUNOS
94 if (p->p_emul == EMUL_SUNOS && type == SOCK_DGRAM)
95 so->so_options |= SO_BROADCAST;
96 #endif
97 *aso = so;
98 return (0);
99 }
100
101 int
102 sobind(so, nam)
103 struct socket *so;
104 struct mbuf *nam;
105 {
106 int s = splnet();
107 int error;
108
109 error =
110 (*so->so_proto->pr_usrreq)(so, PRU_BIND,
111 (struct mbuf *)0, nam, (struct mbuf *)0);
112 splx(s);
113 return (error);
114 }
115
116 int
117 solisten(so, backlog)
118 register struct socket *so;
119 int backlog;
120 {
121 int s = splnet(), error;
122
123 error =
124 (*so->so_proto->pr_usrreq)(so, PRU_LISTEN,
125 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
126 if (error) {
127 splx(s);
128 return (error);
129 }
130 if (so->so_q == 0)
131 so->so_options |= SO_ACCEPTCONN;
132 if (backlog < 0)
133 backlog = 0;
134 so->so_qlimit = min(backlog, SOMAXCONN);
135 splx(s);
136 return (0);
137 }
138
139 int
140 sofree(so)
141 register struct socket *so;
142 {
143
144 if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
145 return;
146 if (so->so_head) {
147 if (!soqremque(so, 0) && !soqremque(so, 1))
148 panic("sofree dq");
149 so->so_head = 0;
150 }
151 sbrelease(&so->so_snd);
152 sorflush(so);
153 FREE(so, M_SOCKET);
154 }
155
156 /*
157 * Close a socket on last file table reference removal.
158 * Initiate disconnect if connected.
159 * Free socket when disconnect complete.
160 */
161 int
162 soclose(so)
163 register struct socket *so;
164 {
165 int s = splnet(); /* conservative */
166 int error = 0;
167
168 if (so->so_options & SO_ACCEPTCONN) {
169 while (so->so_q0)
170 (void) soabort(so->so_q0);
171 while (so->so_q)
172 (void) soabort(so->so_q);
173 }
174 if (so->so_pcb == 0)
175 goto discard;
176 if (so->so_state & SS_ISCONNECTED) {
177 if ((so->so_state & SS_ISDISCONNECTING) == 0) {
178 error = sodisconnect(so);
179 if (error)
180 goto drop;
181 }
182 if (so->so_options & SO_LINGER) {
183 if ((so->so_state & SS_ISDISCONNECTING) &&
184 (so->so_state & SS_NBIO))
185 goto drop;
186 while (so->so_state & SS_ISCONNECTED)
187 if (error = tsleep((caddr_t)&so->so_timeo,
188 PSOCK | PCATCH, netcls, so->so_linger))
189 break;
190 }
191 }
192 drop:
193 if (so->so_pcb) {
194 int error2 =
195 (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
196 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
197 if (error == 0)
198 error = error2;
199 }
200 discard:
201 if (so->so_state & SS_NOFDREF)
202 panic("soclose: NOFDREF");
203 so->so_state |= SS_NOFDREF;
204 sofree(so);
205 splx(s);
206 return (error);
207 }
208
209 /*
210 * Must be called at splnet...
211 */
212 int
213 soabort(so)
214 struct socket *so;
215 {
216
217 return (
218 (*so->so_proto->pr_usrreq)(so, PRU_ABORT,
219 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
220 }
221
222 int
223 soaccept(so, nam)
224 register struct socket *so;
225 struct mbuf *nam;
226 {
227 int s = splnet();
228 int error;
229
230 if ((so->so_state & SS_NOFDREF) == 0)
231 panic("soaccept: !NOFDREF");
232 so->so_state &= ~SS_NOFDREF;
233 error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
234 (struct mbuf *)0, nam, (struct mbuf *)0);
235 splx(s);
236 return (error);
237 }
238
239 int
240 soconnect(so, nam)
241 register struct socket *so;
242 struct mbuf *nam;
243 {
244 int s;
245 int error;
246
247 if (so->so_options & SO_ACCEPTCONN)
248 return (EOPNOTSUPP);
249 s = splnet();
250 /*
251 * If protocol is connection-based, can only connect once.
252 * Otherwise, if connected, try to disconnect first.
253 * This allows user to disconnect by connecting to, e.g.,
254 * a null address.
255 */
256 if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
257 ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
258 (error = sodisconnect(so))))
259 error = EISCONN;
260 else
261 error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
262 (struct mbuf *)0, nam, (struct mbuf *)0);
263 splx(s);
264 return (error);
265 }
266
267 int
268 soconnect2(so1, so2)
269 register struct socket *so1;
270 struct socket *so2;
271 {
272 int s = splnet();
273 int error;
274
275 error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
276 (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
277 splx(s);
278 return (error);
279 }
280
281 int
282 sodisconnect(so)
283 register struct socket *so;
284 {
285 int s = splnet();
286 int error;
287
288 if ((so->so_state & SS_ISCONNECTED) == 0) {
289 error = ENOTCONN;
290 goto bad;
291 }
292 if (so->so_state & SS_ISDISCONNECTING) {
293 error = EALREADY;
294 goto bad;
295 }
296 error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
297 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
298 bad:
299 splx(s);
300 return (error);
301 }
302
303 #define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
304 /*
305 * Send on a socket.
306 * If send must go all at once and message is larger than
307 * send buffering, then hard error.
308 * Lock against other senders.
309 * If must go all at once and not enough room now, then
310 * inform user that this would block and do nothing.
311 * Otherwise, if nonblocking, send as much as possible.
312 * The data to be sent is described by "uio" if nonzero,
313 * otherwise by the mbuf chain "top" (which must be null
314 * if uio is not). Data provided in mbuf chain must be small
315 * enough to send all at once.
316 *
317 * Returns nonzero on error, timeout or signal; callers
318 * must check for short counts if EINTR/ERESTART are returned.
319 * Data and control buffers are freed on return.
320 */
321 int
322 sosend(so, addr, uio, top, control, flags)
323 register struct socket *so;
324 struct mbuf *addr;
325 struct uio *uio;
326 struct mbuf *top;
327 struct mbuf *control;
328 int flags;
329 {
330 struct proc *p = curproc; /* XXX */
331 struct mbuf **mp;
332 register struct mbuf *m;
333 register long space, len, resid;
334 int clen = 0, error, s, dontroute, mlen;
335 int atomic = sosendallatonce(so) || top;
336
337 if (uio)
338 resid = uio->uio_resid;
339 else
340 resid = top->m_pkthdr.len;
341 /*
342 * In theory resid should be unsigned.
343 * However, space must be signed, as it might be less than 0
344 * if we over-committed, and we must use a signed comparison
345 * of space and resid. On the other hand, a negative resid
346 * causes us to loop sending 0-length segments to the protocol.
347 */
348 if (resid < 0)
349 return (EINVAL);
350 dontroute =
351 (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
352 (so->so_proto->pr_flags & PR_ATOMIC);
353 p->p_stats->p_ru.ru_msgsnd++;
354 if (control)
355 clen = control->m_len;
356 #define snderr(errno) { error = errno; splx(s); goto release; }
357
358 restart:
359 if (error = sblock(&so->so_snd, SBLOCKWAIT(flags)))
360 goto out;
361 do {
362 s = splnet();
363 if (so->so_state & SS_CANTSENDMORE)
364 snderr(EPIPE);
365 if (so->so_error)
366 snderr(so->so_error);
367 if ((so->so_state & SS_ISCONNECTED) == 0) {
368 if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
369 if ((so->so_state & SS_ISCONFIRMING) == 0 &&
370 !(resid == 0 && clen != 0))
371 snderr(ENOTCONN);
372 } else if (addr == 0)
373 snderr(EDESTADDRREQ);
374 }
375 space = sbspace(&so->so_snd);
376 if (flags & MSG_OOB)
377 space += 1024;
378 if (atomic && resid > so->so_snd.sb_hiwat ||
379 clen > so->so_snd.sb_hiwat)
380 snderr(EMSGSIZE);
381 if (space < resid + clen && uio &&
382 (atomic || space < so->so_snd.sb_lowat || space < clen)) {
383 if (so->so_state & SS_NBIO)
384 snderr(EWOULDBLOCK);
385 sbunlock(&so->so_snd);
386 error = sbwait(&so->so_snd);
387 splx(s);
388 if (error)
389 goto out;
390 goto restart;
391 }
392 splx(s);
393 mp = ⊤
394 space -= clen;
395 do {
396 if (uio == NULL) {
397 /*
398 * Data is prepackaged in "top".
399 */
400 resid = 0;
401 if (flags & MSG_EOR)
402 top->m_flags |= M_EOR;
403 } else do {
404 if (top == 0) {
405 MGETHDR(m, M_WAIT, MT_DATA);
406 mlen = MHLEN;
407 m->m_pkthdr.len = 0;
408 m->m_pkthdr.rcvif = (struct ifnet *)0;
409 } else {
410 MGET(m, M_WAIT, MT_DATA);
411 mlen = MLEN;
412 }
413 if (resid >= MINCLSIZE && space >= MCLBYTES) {
414 MCLGET(m, M_WAIT);
415 if ((m->m_flags & M_EXT) == 0)
416 goto nopages;
417 mlen = MCLBYTES;
418 #ifdef MAPPED_MBUFS
419 len = min(MCLBYTES, resid);
420 #else
421 if (atomic && top == 0) {
422 len = min(MCLBYTES - max_hdr, resid);
423 m->m_data += max_hdr;
424 } else
425 len = min(MCLBYTES, resid);
426 #endif
427 space -= MCLBYTES;
428 } else {
429 nopages:
430 len = min(min(mlen, resid), space);
431 space -= len;
432 /*
433 * For datagram protocols, leave room
434 * for protocol headers in first mbuf.
435 */
436 if (atomic && top == 0 && len < mlen)
437 MH_ALIGN(m, len);
438 }
439 error = uiomove(mtod(m, caddr_t), (int)len, uio);
440 resid = uio->uio_resid;
441 m->m_len = len;
442 *mp = m;
443 top->m_pkthdr.len += len;
444 if (error)
445 goto release;
446 mp = &m->m_next;
447 if (resid <= 0) {
448 if (flags & MSG_EOR)
449 top->m_flags |= M_EOR;
450 break;
451 }
452 } while (space > 0 && atomic);
453 if (dontroute)
454 so->so_options |= SO_DONTROUTE;
455 s = splnet(); /* XXX */
456 error = (*so->so_proto->pr_usrreq)(so,
457 (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
458 top, addr, control);
459 splx(s);
460 if (dontroute)
461 so->so_options &= ~SO_DONTROUTE;
462 clen = 0;
463 control = 0;
464 top = 0;
465 mp = ⊤
466 if (error)
467 goto release;
468 } while (resid && space > 0);
469 } while (resid);
470
471 release:
472 sbunlock(&so->so_snd);
473 out:
474 if (top)
475 m_freem(top);
476 if (control)
477 m_freem(control);
478 return (error);
479 }
480
481 /*
482 * Implement receive operations on a socket.
483 * We depend on the way that records are added to the sockbuf
484 * by sbappend*. In particular, each record (mbufs linked through m_next)
485 * must begin with an address if the protocol so specifies,
486 * followed by an optional mbuf or mbufs containing ancillary data,
487 * and then zero or more mbufs of data.
488 * In order to avoid blocking network interrupts for the entire time here,
489 * we splx() while doing the actual copy to user space.
490 * Although the sockbuf is locked, new data may still be appended,
491 * and thus we must maintain consistency of the sockbuf during that time.
492 *
493 * The caller may receive the data as a single mbuf chain by supplying
494 * an mbuf **mp0 for use in returning the chain. The uio is then used
495 * only for the count in uio_resid.
496 */
497 int
498 soreceive(so, paddr, uio, mp0, controlp, flagsp)
499 register struct socket *so;
500 struct mbuf **paddr;
501 struct uio *uio;
502 struct mbuf **mp0;
503 struct mbuf **controlp;
504 int *flagsp;
505 {
506 register struct mbuf *m, **mp;
507 register int flags, len, error, s, offset;
508 struct protosw *pr = so->so_proto;
509 struct mbuf *nextrecord;
510 int moff, type;
511 int orig_resid = uio->uio_resid;
512
513 mp = mp0;
514 if (paddr)
515 *paddr = 0;
516 if (controlp)
517 *controlp = 0;
518 if (flagsp)
519 flags = *flagsp &~ MSG_EOR;
520 else
521 flags = 0;
522 if (flags & MSG_OOB) {
523 m = m_get(M_WAIT, MT_DATA);
524 error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
525 m, (struct mbuf *)(flags & MSG_PEEK), (struct mbuf *)0);
526 if (error)
527 goto bad;
528 do {
529 error = uiomove(mtod(m, caddr_t),
530 (int) min(uio->uio_resid, m->m_len), uio);
531 m = m_free(m);
532 } while (uio->uio_resid && error == 0 && m);
533 bad:
534 if (m)
535 m_freem(m);
536 return (error);
537 }
538 if (mp)
539 *mp = (struct mbuf *)0;
540 if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
541 (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
542 (struct mbuf *)0, (struct mbuf *)0);
543
544 restart:
545 if (error = sblock(&so->so_rcv, SBLOCKWAIT(flags)))
546 return (error);
547 s = splnet();
548
549 m = so->so_rcv.sb_mb;
550 /*
551 * If we have less data than requested, block awaiting more
552 * (subject to any timeout) if:
553 * 1. the current count is less than the low water mark,
554 * 2. MSG_WAITALL is set, and it is possible to do the entire
555 * receive operation at once if we block (resid <= hiwat), or
556 * 3. MSG_DONTWAIT is not set.
557 * If MSG_WAITALL is set but resid is larger than the receive buffer,
558 * we have to do the receive in sections, and thus risk returning
559 * a short count if a timeout or signal occurs after we start.
560 */
561 if (m == 0 || ((flags & MSG_DONTWAIT) == 0 &&
562 so->so_rcv.sb_cc < uio->uio_resid) &&
563 (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
564 ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) &&
565 m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0) {
566 #ifdef DIAGNOSTIC
567 if (m == 0 && so->so_rcv.sb_cc)
568 panic("receive 1");
569 #endif
570 if (so->so_error) {
571 if (m)
572 goto dontblock;
573 error = so->so_error;
574 if ((flags & MSG_PEEK) == 0)
575 so->so_error = 0;
576 goto release;
577 }
578 if (so->so_state & SS_CANTRCVMORE) {
579 if (m)
580 goto dontblock;
581 else
582 goto release;
583 }
584 for (; m; m = m->m_next)
585 if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) {
586 m = so->so_rcv.sb_mb;
587 goto dontblock;
588 }
589 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
590 (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
591 error = ENOTCONN;
592 goto release;
593 }
594 if (uio->uio_resid == 0)
595 goto release;
596 if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
597 error = EWOULDBLOCK;
598 goto release;
599 }
600 sbunlock(&so->so_rcv);
601 error = sbwait(&so->so_rcv);
602 splx(s);
603 if (error)
604 return (error);
605 goto restart;
606 }
607 dontblock:
608 #ifdef notyet /* XXXX */
609 if (uio->uio_procp)
610 uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
611 #endif
612 nextrecord = m->m_nextpkt;
613 if (pr->pr_flags & PR_ADDR) {
614 #ifdef DIAGNOSTIC
615 if (m->m_type != MT_SONAME)
616 panic("receive 1a");
617 #endif
618 orig_resid = 0;
619 if (flags & MSG_PEEK) {
620 if (paddr)
621 *paddr = m_copy(m, 0, m->m_len);
622 m = m->m_next;
623 } else {
624 sbfree(&so->so_rcv, m);
625 if (paddr) {
626 *paddr = m;
627 so->so_rcv.sb_mb = m->m_next;
628 m->m_next = 0;
629 m = so->so_rcv.sb_mb;
630 } else {
631 MFREE(m, so->so_rcv.sb_mb);
632 m = so->so_rcv.sb_mb;
633 }
634 }
635 }
636 while (m && m->m_type == MT_CONTROL && error == 0) {
637 if (flags & MSG_PEEK) {
638 if (controlp)
639 *controlp = m_copy(m, 0, m->m_len);
640 m = m->m_next;
641 } else {
642 sbfree(&so->so_rcv, m);
643 if (controlp) {
644 if (pr->pr_domain->dom_externalize &&
645 mtod(m, struct cmsghdr *)->cmsg_type ==
646 SCM_RIGHTS)
647 error = (*pr->pr_domain->dom_externalize)(m);
648 *controlp = m;
649 so->so_rcv.sb_mb = m->m_next;
650 m->m_next = 0;
651 m = so->so_rcv.sb_mb;
652 } else {
653 MFREE(m, so->so_rcv.sb_mb);
654 m = so->so_rcv.sb_mb;
655 }
656 }
657 if (controlp) {
658 orig_resid = 0;
659 controlp = &(*controlp)->m_next;
660 }
661 }
662 if (m) {
663 if ((flags & MSG_PEEK) == 0)
664 m->m_nextpkt = nextrecord;
665 type = m->m_type;
666 if (type == MT_OOBDATA)
667 flags |= MSG_OOB;
668 }
669 moff = 0;
670 offset = 0;
671 while (m && uio->uio_resid > 0 && error == 0) {
672 if (m->m_type == MT_OOBDATA) {
673 if (type != MT_OOBDATA)
674 break;
675 } else if (type == MT_OOBDATA)
676 break;
677 #ifdef DIAGNOSTIC
678 else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
679 panic("receive 3");
680 #endif
681 so->so_state &= ~SS_RCVATMARK;
682 len = uio->uio_resid;
683 if (so->so_oobmark && len > so->so_oobmark - offset)
684 len = so->so_oobmark - offset;
685 if (len > m->m_len - moff)
686 len = m->m_len - moff;
687 /*
688 * If mp is set, just pass back the mbufs.
689 * Otherwise copy them out via the uio, then free.
690 * Sockbuf must be consistent here (points to current mbuf,
691 * it points to next record) when we drop priority;
692 * we must note any additions to the sockbuf when we
693 * block interrupts again.
694 */
695 if (mp == 0) {
696 splx(s);
697 error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);
698 s = splnet();
699 } else
700 uio->uio_resid -= len;
701 if (len == m->m_len - moff) {
702 if (m->m_flags & M_EOR)
703 flags |= MSG_EOR;
704 if (flags & MSG_PEEK) {
705 m = m->m_next;
706 moff = 0;
707 } else {
708 nextrecord = m->m_nextpkt;
709 sbfree(&so->so_rcv, m);
710 if (mp) {
711 *mp = m;
712 mp = &m->m_next;
713 so->so_rcv.sb_mb = m = m->m_next;
714 *mp = (struct mbuf *)0;
715 } else {
716 MFREE(m, so->so_rcv.sb_mb);
717 m = so->so_rcv.sb_mb;
718 }
719 if (m)
720 m->m_nextpkt = nextrecord;
721 }
722 } else {
723 if (flags & MSG_PEEK)
724 moff += len;
725 else {
726 if (mp)
727 *mp = m_copym(m, 0, len, M_WAIT);
728 m->m_data += len;
729 m->m_len -= len;
730 so->so_rcv.sb_cc -= len;
731 }
732 }
733 if (so->so_oobmark) {
734 if ((flags & MSG_PEEK) == 0) {
735 so->so_oobmark -= len;
736 if (so->so_oobmark == 0) {
737 so->so_state |= SS_RCVATMARK;
738 break;
739 }
740 } else {
741 offset += len;
742 if (offset == so->so_oobmark)
743 break;
744 }
745 }
746 if (flags & MSG_EOR)
747 break;
748 /*
749 * If the MSG_WAITALL flag is set (for non-atomic socket),
750 * we must not quit until "uio->uio_resid == 0" or an error
751 * termination. If a signal/timeout occurs, return
752 * with a short count but without error.
753 * Keep sockbuf locked against other readers.
754 */
755 while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&
756 !sosendallatonce(so) && !nextrecord) {
757 if (so->so_error || so->so_state & SS_CANTRCVMORE)
758 break;
759 error = sbwait(&so->so_rcv);
760 if (error) {
761 sbunlock(&so->so_rcv);
762 splx(s);
763 return (0);
764 }
765 if (m = so->so_rcv.sb_mb)
766 nextrecord = m->m_nextpkt;
767 }
768 }
769
770 if (m && pr->pr_flags & PR_ATOMIC) {
771 flags |= MSG_TRUNC;
772 if ((flags & MSG_PEEK) == 0)
773 (void) sbdroprecord(&so->so_rcv);
774 }
775 if ((flags & MSG_PEEK) == 0) {
776 if (m == 0)
777 so->so_rcv.sb_mb = nextrecord;
778 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
779 (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
780 (struct mbuf *)flags, (struct mbuf *)0,
781 (struct mbuf *)0);
782 }
783 if (orig_resid == uio->uio_resid && orig_resid &&
784 (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
785 sbunlock(&so->so_rcv);
786 splx(s);
787 goto restart;
788 }
789
790 if (flagsp)
791 *flagsp |= flags;
792 release:
793 sbunlock(&so->so_rcv);
794 splx(s);
795 return (error);
796 }
797
798 int
799 soshutdown(so, how)
800 register struct socket *so;
801 register int how;
802 {
803 register struct protosw *pr = so->so_proto;
804
805 how++;
806 if (how & FREAD)
807 sorflush(so);
808 if (how & FWRITE)
809 return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN,
810 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
811 return (0);
812 }
813
814 void
815 sorflush(so)
816 register struct socket *so;
817 {
818 register struct sockbuf *sb = &so->so_rcv;
819 register struct protosw *pr = so->so_proto;
820 register int s;
821 struct sockbuf asb;
822
823 sb->sb_flags |= SB_NOINTR;
824 (void) sblock(sb, M_WAITOK);
825 s = splimp();
826 socantrcvmore(so);
827 sbunlock(sb);
828 asb = *sb;
829 bzero((caddr_t)sb, sizeof (*sb));
830 splx(s);
831 if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
832 (*pr->pr_domain->dom_dispose)(asb.sb_mb);
833 sbrelease(&asb);
834 }
835
836 int
837 sosetopt(so, level, optname, m0)
838 register struct socket *so;
839 int level, optname;
840 struct mbuf *m0;
841 {
842 int error = 0;
843 register struct mbuf *m = m0;
844
845 if (level != SOL_SOCKET) {
846 if (so->so_proto && so->so_proto->pr_ctloutput)
847 return ((*so->so_proto->pr_ctloutput)
848 (PRCO_SETOPT, so, level, optname, &m0));
849 error = ENOPROTOOPT;
850 } else {
851 switch (optname) {
852
853 case SO_LINGER:
854 if (m == NULL || m->m_len != sizeof (struct linger)) {
855 error = EINVAL;
856 goto bad;
857 }
858 so->so_linger = mtod(m, struct linger *)->l_linger;
859 /* fall thru... */
860
861 case SO_DEBUG:
862 case SO_KEEPALIVE:
863 case SO_DONTROUTE:
864 case SO_USELOOPBACK:
865 case SO_BROADCAST:
866 case SO_REUSEADDR:
867 case SO_REUSEPORT:
868 case SO_OOBINLINE:
869 if (m == NULL || m->m_len < sizeof (int)) {
870 error = EINVAL;
871 goto bad;
872 }
873 if (*mtod(m, int *))
874 so->so_options |= optname;
875 else
876 so->so_options &= ~optname;
877 break;
878
879 case SO_SNDBUF:
880 case SO_RCVBUF:
881 case SO_SNDLOWAT:
882 case SO_RCVLOWAT:
883 if (m == NULL || m->m_len < sizeof (int)) {
884 error = EINVAL;
885 goto bad;
886 }
887 switch (optname) {
888
889 case SO_SNDBUF:
890 case SO_RCVBUF:
891 if (sbreserve(optname == SO_SNDBUF ?
892 &so->so_snd : &so->so_rcv,
893 (u_long) *mtod(m, int *)) == 0) {
894 error = ENOBUFS;
895 goto bad;
896 }
897 break;
898
899 case SO_SNDLOWAT:
900 so->so_snd.sb_lowat = *mtod(m, int *);
901 break;
902 case SO_RCVLOWAT:
903 so->so_rcv.sb_lowat = *mtod(m, int *);
904 break;
905 }
906 break;
907
908 case SO_SNDTIMEO:
909 case SO_RCVTIMEO:
910 {
911 struct timeval *tv;
912 short val;
913
914 if (m == NULL || m->m_len < sizeof (*tv)) {
915 error = EINVAL;
916 goto bad;
917 }
918 tv = mtod(m, struct timeval *);
919 if (tv->tv_sec > SHRT_MAX / hz - hz) {
920 error = EDOM;
921 goto bad;
922 }
923 val = tv->tv_sec * hz + tv->tv_usec / tick;
924
925 switch (optname) {
926
927 case SO_SNDTIMEO:
928 so->so_snd.sb_timeo = val;
929 break;
930 case SO_RCVTIMEO:
931 so->so_rcv.sb_timeo = val;
932 break;
933 }
934 break;
935 }
936
937 default:
938 error = ENOPROTOOPT;
939 break;
940 }
941 if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
942 (void) ((*so->so_proto->pr_ctloutput)
943 (PRCO_SETOPT, so, level, optname, &m0));
944 m = NULL; /* freed by protocol */
945 }
946 }
947 bad:
948 if (m)
949 (void) m_free(m);
950 return (error);
951 }
952
953 int
954 sogetopt(so, level, optname, mp)
955 register struct socket *so;
956 int level, optname;
957 struct mbuf **mp;
958 {
959 register struct mbuf *m;
960
961 if (level != SOL_SOCKET) {
962 if (so->so_proto && so->so_proto->pr_ctloutput) {
963 return ((*so->so_proto->pr_ctloutput)
964 (PRCO_GETOPT, so, level, optname, mp));
965 } else
966 return (ENOPROTOOPT);
967 } else {
968 m = m_get(M_WAIT, MT_SOOPTS);
969 m->m_len = sizeof (int);
970
971 switch (optname) {
972
973 case SO_LINGER:
974 m->m_len = sizeof (struct linger);
975 mtod(m, struct linger *)->l_onoff =
976 so->so_options & SO_LINGER;
977 mtod(m, struct linger *)->l_linger = so->so_linger;
978 break;
979
980 case SO_USELOOPBACK:
981 case SO_DONTROUTE:
982 case SO_DEBUG:
983 case SO_KEEPALIVE:
984 case SO_REUSEADDR:
985 case SO_REUSEPORT:
986 case SO_BROADCAST:
987 case SO_OOBINLINE:
988 *mtod(m, int *) = so->so_options & optname;
989 break;
990
991 case SO_TYPE:
992 *mtod(m, int *) = so->so_type;
993 break;
994
995 case SO_ERROR:
996 *mtod(m, int *) = so->so_error;
997 so->so_error = 0;
998 break;
999
1000 case SO_SNDBUF:
1001 *mtod(m, int *) = so->so_snd.sb_hiwat;
1002 break;
1003
1004 case SO_RCVBUF:
1005 *mtod(m, int *) = so->so_rcv.sb_hiwat;
1006 break;
1007
1008 case SO_SNDLOWAT:
1009 *mtod(m, int *) = so->so_snd.sb_lowat;
1010 break;
1011
1012 case SO_RCVLOWAT:
1013 *mtod(m, int *) = so->so_rcv.sb_lowat;
1014 break;
1015
1016 case SO_SNDTIMEO:
1017 case SO_RCVTIMEO:
1018 {
1019 int val = (optname == SO_SNDTIMEO ?
1020 so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
1021
1022 m->m_len = sizeof(struct timeval);
1023 mtod(m, struct timeval *)->tv_sec = val / hz;
1024 mtod(m, struct timeval *)->tv_usec =
1025 (val % hz) / tick;
1026 break;
1027 }
1028
1029 default:
1030 (void)m_free(m);
1031 return (ENOPROTOOPT);
1032 }
1033 *mp = m;
1034 return (0);
1035 }
1036 }
1037
1038 void
1039 sohasoutofband(so)
1040 register struct socket *so;
1041 {
1042 struct proc *p;
1043
1044 if (so->so_pgid < 0)
1045 gsignal(-so->so_pgid, SIGURG);
1046 else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
1047 psignal(p, SIGURG);
1048 selwakeup(&so->so_rcv.sb_sel);
1049 }
1050