This source file includes following definitions.
- soinit
- socreate
- sobind
- solisten
- sofree
- soclose
- soabort
- soaccept
- soconnect
- soconnect2
- sodisconnect
- sosend
- soreceive
- soshutdown
- sorflush
- sosetopt
- sogetopt
- sohasoutofband
- soo_kqfilter
- filt_sordetach
- filt_soread
- filt_sowdetach
- filt_sowrite
- filt_solisten
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/proc.h>
38 #include <sys/file.h>
39 #include <sys/malloc.h>
40 #include <sys/mbuf.h>
41 #include <sys/domain.h>
42 #include <sys/kernel.h>
43 #include <sys/event.h>
44 #include <sys/protosw.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/signalvar.h>
48 #include <sys/resourcevar.h>
49 #include <sys/pool.h>
50
51 void filt_sordetach(struct knote *kn);
52 int filt_soread(struct knote *kn, long hint);
53 void filt_sowdetach(struct knote *kn);
54 int filt_sowrite(struct knote *kn, long hint);
55 int filt_solisten(struct knote *kn, long hint);
56
57 struct filterops solisten_filtops =
58 { 1, NULL, filt_sordetach, filt_solisten };
59 struct filterops soread_filtops =
60 { 1, NULL, filt_sordetach, filt_soread };
61 struct filterops sowrite_filtops =
62 { 1, NULL, filt_sowdetach, filt_sowrite };
63
64
65 #ifndef SOMINCONN
66 #define SOMINCONN 80
67 #endif
68
69 int somaxconn = SOMAXCONN;
70 int sominconn = SOMINCONN;
71
72 struct pool socket_pool;
73
74 void
75 soinit(void)
76 {
77
78 pool_init(&socket_pool, sizeof(struct socket), 0, 0, 0, "sockpl", NULL);
79 }
80
81
82
83
84
85
86
87
88
89 int
90 socreate(int dom, struct socket **aso, int type, int proto)
91 {
92 struct proc *p = curproc;
93 struct protosw *prp;
94 struct socket *so;
95 int error, s;
96
97 if (proto)
98 prp = pffindproto(dom, proto, type);
99 else
100 prp = pffindtype(dom, type);
101 if (prp == NULL || prp->pr_usrreq == 0)
102 return (EPROTONOSUPPORT);
103 if (prp->pr_type != type)
104 return (EPROTOTYPE);
105 s = splsoftnet();
106 so = pool_get(&socket_pool, PR_WAITOK);
107 bzero(so, sizeof(*so));
108 TAILQ_INIT(&so->so_q0);
109 TAILQ_INIT(&so->so_q);
110 so->so_type = type;
111 if (p->p_ucred->cr_uid == 0)
112 so->so_state = SS_PRIV;
113 so->so_ruid = p->p_cred->p_ruid;
114 so->so_euid = p->p_ucred->cr_uid;
115 so->so_rgid = p->p_cred->p_rgid;
116 so->so_egid = p->p_ucred->cr_gid;
117 so->so_cpid = p->p_pid;
118 so->so_proto = prp;
119 error = (*prp->pr_usrreq)(so, PRU_ATTACH, NULL,
120 (struct mbuf *)(long)proto, NULL);
121 if (error) {
122 so->so_state |= SS_NOFDREF;
123 sofree(so);
124 splx(s);
125 return (error);
126 }
127 #ifdef COMPAT_SUNOS
128 {
129 extern struct emul emul_sunos;
130 if (p->p_emul == &emul_sunos && type == SOCK_DGRAM)
131 so->so_options |= SO_BROADCAST;
132 }
133 #endif
134 splx(s);
135 *aso = so;
136 return (0);
137 }
138
139 int
140 sobind(struct socket *so, struct mbuf *nam)
141 {
142 int s = splsoftnet();
143 int error;
144
145 error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, NULL, nam, NULL);
146 splx(s);
147 return (error);
148 }
149
150 int
151 solisten(struct socket *so, int backlog)
152 {
153 int s = splsoftnet(), error;
154
155 error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL, NULL, NULL);
156 if (error) {
157 splx(s);
158 return (error);
159 }
160 if (TAILQ_FIRST(&so->so_q) == NULL)
161 so->so_options |= SO_ACCEPTCONN;
162 if (backlog < 0 || backlog > somaxconn)
163 backlog = somaxconn;
164 if (backlog < sominconn)
165 backlog = sominconn;
166 so->so_qlimit = backlog;
167 splx(s);
168 return (0);
169 }
170
171
172
173
174
175 void
176 sofree(struct socket *so)
177 {
178 splassert(IPL_SOFTNET);
179
180 if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
181 return;
182 if (so->so_head) {
183
184
185
186
187
188 if (!soqremque(so, 0))
189 return;
190 }
191 sbrelease(&so->so_snd);
192 sorflush(so);
193 pool_put(&socket_pool, so);
194 }
195
196
197
198
199
200
201 int
202 soclose(struct socket *so)
203 {
204 struct socket *so2;
205 int s = splsoftnet();
206 int error = 0;
207
208 if (so->so_options & SO_ACCEPTCONN) {
209 while ((so2 = TAILQ_FIRST(&so->so_q0)) != NULL) {
210 (void) soqremque(so2, 0);
211 (void) soabort(so2);
212 }
213 while ((so2 = TAILQ_FIRST(&so->so_q)) != NULL) {
214 (void) soqremque(so2, 1);
215 (void) soabort(so2);
216 }
217 }
218 if (so->so_pcb == 0)
219 goto discard;
220 if (so->so_state & SS_ISCONNECTED) {
221 if ((so->so_state & SS_ISDISCONNECTING) == 0) {
222 error = sodisconnect(so);
223 if (error)
224 goto drop;
225 }
226 if (so->so_options & SO_LINGER) {
227 if ((so->so_state & SS_ISDISCONNECTING) &&
228 (so->so_state & SS_NBIO))
229 goto drop;
230 while (so->so_state & SS_ISCONNECTED) {
231 error = tsleep(&so->so_timeo,
232 PSOCK | PCATCH, netcls,
233 so->so_linger * hz);
234 if (error)
235 break;
236 }
237 }
238 }
239 drop:
240 if (so->so_pcb) {
241 int error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH, NULL,
242 NULL, NULL);
243 if (error == 0)
244 error = error2;
245 }
246 discard:
247 if (so->so_state & SS_NOFDREF)
248 panic("soclose: NOFDREF");
249 so->so_state |= SS_NOFDREF;
250 sofree(so);
251 splx(s);
252 return (error);
253 }
254
255
256
257
258 int
259 soabort(struct socket *so)
260 {
261 splassert(IPL_SOFTNET);
262
263 return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, NULL, NULL, NULL);
264 }
265
266 int
267 soaccept(struct socket *so, struct mbuf *nam)
268 {
269 int s = splsoftnet();
270 int error = 0;
271
272 if ((so->so_state & SS_NOFDREF) == 0)
273 panic("soaccept: !NOFDREF");
274 so->so_state &= ~SS_NOFDREF;
275 if ((so->so_state & SS_ISDISCONNECTED) == 0 ||
276 (so->so_proto->pr_flags & PR_ABRTACPTDIS) == 0)
277 error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, NULL,
278 nam, NULL);
279 else
280 error = ECONNABORTED;
281 splx(s);
282 return (error);
283 }
284
285 int
286 soconnect(struct socket *so, struct mbuf *nam)
287 {
288 int s;
289 int error;
290
291 if (so->so_options & SO_ACCEPTCONN)
292 return (EOPNOTSUPP);
293 s = splsoftnet();
294
295
296
297
298
299
300 if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
301 ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
302 (error = sodisconnect(so))))
303 error = EISCONN;
304 else
305 error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
306 NULL, nam, NULL);
307 splx(s);
308 return (error);
309 }
310
311 int
312 soconnect2(struct socket *so1, struct socket *so2)
313 {
314 int s = splsoftnet();
315 int error;
316
317 error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, NULL,
318 (struct mbuf *)so2, NULL);
319 splx(s);
320 return (error);
321 }
322
323 int
324 sodisconnect(struct socket *so)
325 {
326 int s = splsoftnet();
327 int error;
328
329 if ((so->so_state & SS_ISCONNECTED) == 0) {
330 error = ENOTCONN;
331 goto bad;
332 }
333 if (so->so_state & SS_ISDISCONNECTING) {
334 error = EALREADY;
335 goto bad;
336 }
337 error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, NULL, NULL,
338 NULL);
339 bad:
340 splx(s);
341 return (error);
342 }
343
344 #define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 int
363 sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
364 struct mbuf *control, int flags)
365 {
366 struct mbuf **mp;
367 struct mbuf *m;
368 long space, len, mlen, clen = 0;
369 quad_t resid;
370 int error, s, dontroute;
371 int atomic = sosendallatonce(so) || top;
372
373 if (uio)
374 resid = uio->uio_resid;
375 else
376 resid = top->m_pkthdr.len;
377
378
379
380
381
382
383
384
385 if (resid < 0 ||
386 (so->so_type == SOCK_STREAM && (flags & MSG_EOR))) {
387 error = EINVAL;
388 goto out;
389 }
390 dontroute =
391 (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
392 (so->so_proto->pr_flags & PR_ATOMIC);
393 if (uio && uio->uio_procp)
394 uio->uio_procp->p_stats->p_ru.ru_msgsnd++;
395 if (control)
396 clen = control->m_len;
397 #define snderr(errno) { error = errno; splx(s); goto release; }
398
399 restart:
400 if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
401 goto out;
402 so->so_state |= SS_ISSENDING;
403 do {
404 s = splsoftnet();
405 if (so->so_state & SS_CANTSENDMORE)
406 snderr(EPIPE);
407 if (so->so_error) {
408 error = so->so_error;
409 so->so_error = 0;
410 splx(s);
411 goto release;
412 }
413 if ((so->so_state & SS_ISCONNECTED) == 0) {
414 if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
415 if ((so->so_state & SS_ISCONFIRMING) == 0 &&
416 !(resid == 0 && clen != 0))
417 snderr(ENOTCONN);
418 } else if (addr == 0)
419 snderr(EDESTADDRREQ);
420 }
421 space = sbspace(&so->so_snd);
422 if (flags & MSG_OOB)
423 space += 1024;
424 if ((atomic && resid > so->so_snd.sb_hiwat) ||
425 clen > so->so_snd.sb_hiwat)
426 snderr(EMSGSIZE);
427 if (space < resid + clen && uio &&
428 (atomic || space < so->so_snd.sb_lowat || space < clen)) {
429 if (so->so_state & SS_NBIO)
430 snderr(EWOULDBLOCK);
431 sbunlock(&so->so_snd);
432 error = sbwait(&so->so_snd);
433 so->so_state &= ~SS_ISSENDING;
434 splx(s);
435 if (error)
436 goto out;
437 goto restart;
438 }
439 splx(s);
440 mp = ⊤
441 space -= clen;
442 do {
443 if (uio == NULL) {
444
445
446
447 resid = 0;
448 if (flags & MSG_EOR)
449 top->m_flags |= M_EOR;
450 } else do {
451 if (top == 0) {
452 MGETHDR(m, M_WAIT, MT_DATA);
453 mlen = MHLEN;
454 m->m_pkthdr.len = 0;
455 m->m_pkthdr.rcvif = (struct ifnet *)0;
456 } else {
457 MGET(m, M_WAIT, MT_DATA);
458 mlen = MLEN;
459 }
460 if (resid >= MINCLSIZE && space >= MCLBYTES) {
461 MCLGET(m, M_WAIT);
462 if ((m->m_flags & M_EXT) == 0)
463 goto nopages;
464 mlen = MCLBYTES;
465 if (atomic && top == 0) {
466 len = lmin(MCLBYTES - max_hdr, resid);
467 m->m_data += max_hdr;
468 } else
469 len = lmin(MCLBYTES, resid);
470 space -= len;
471 } else {
472 nopages:
473 len = lmin(lmin(mlen, resid), space);
474 space -= len;
475
476
477
478
479 if (atomic && top == 0 && len < mlen)
480 MH_ALIGN(m, len);
481 }
482 error = uiomove(mtod(m, caddr_t), (int)len,
483 uio);
484 resid = uio->uio_resid;
485 m->m_len = len;
486 *mp = m;
487 top->m_pkthdr.len += len;
488 if (error)
489 goto release;
490 mp = &m->m_next;
491 if (resid <= 0) {
492 if (flags & MSG_EOR)
493 top->m_flags |= M_EOR;
494 break;
495 }
496 } while (space > 0 && atomic);
497 if (dontroute)
498 so->so_options |= SO_DONTROUTE;
499 s = splsoftnet();
500 if (resid <= 0)
501 so->so_state &= ~SS_ISSENDING;
502 error = (*so->so_proto->pr_usrreq)(so,
503 (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
504 top, addr, control);
505 splx(s);
506 if (dontroute)
507 so->so_options &= ~SO_DONTROUTE;
508 clen = 0;
509 control = 0;
510 top = 0;
511 mp = ⊤
512 if (error)
513 goto release;
514 } while (resid && space > 0);
515 } while (resid);
516
517 release:
518 so->so_state &= ~SS_ISSENDING;
519 sbunlock(&so->so_snd);
520 out:
521 if (top)
522 m_freem(top);
523 if (control)
524 m_freem(control);
525 return (error);
526 }
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 int
545 soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
546 struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
547 {
548 struct mbuf *m, **mp;
549 int flags, len, error, s, offset;
550 struct protosw *pr = so->so_proto;
551 struct mbuf *nextrecord;
552 int moff, type = 0;
553 size_t orig_resid = uio->uio_resid;
554 int uio_error = 0;
555 int resid;
556
557 mp = mp0;
558 if (paddr)
559 *paddr = 0;
560 if (controlp)
561 *controlp = 0;
562 if (flagsp)
563 flags = *flagsp &~ MSG_EOR;
564 else
565 flags = 0;
566 if (so->so_state & SS_NBIO)
567 flags |= MSG_DONTWAIT;
568 if (flags & MSG_OOB) {
569 m = m_get(M_WAIT, MT_DATA);
570 error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
571 (struct mbuf *)(long)(flags & MSG_PEEK), NULL);
572 if (error)
573 goto bad;
574 do {
575 error = uiomove(mtod(m, caddr_t),
576 (int) min(uio->uio_resid, m->m_len), uio);
577 m = m_free(m);
578 } while (uio->uio_resid && error == 0 && m);
579 bad:
580 if (m)
581 m_freem(m);
582 return (error);
583 }
584 if (mp)
585 *mp = NULL;
586 if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
587 (*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL);
588
589 restart:
590 if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
591 return (error);
592 s = splsoftnet();
593
594 m = so->so_rcv.sb_mb;
595
596
597
598
599
600
601
602
603
604
605
606 if (m == NULL || (((flags & MSG_DONTWAIT) == 0 &&
607 so->so_rcv.sb_cc < uio->uio_resid) &&
608 (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
609 ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) &&
610 m->m_nextpkt == NULL && (pr->pr_flags & PR_ATOMIC) == 0)) {
611 #ifdef DIAGNOSTIC
612 if (m == NULL && so->so_rcv.sb_cc)
613 panic("receive 1");
614 #endif
615 if (so->so_error) {
616 if (m)
617 goto dontblock;
618 error = so->so_error;
619 if ((flags & MSG_PEEK) == 0)
620 so->so_error = 0;
621 goto release;
622 }
623 if (so->so_state & SS_CANTRCVMORE) {
624 if (m)
625 goto dontblock;
626 else
627 goto release;
628 }
629 for (; m; m = m->m_next)
630 if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) {
631 m = so->so_rcv.sb_mb;
632 goto dontblock;
633 }
634 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
635 (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
636 error = ENOTCONN;
637 goto release;
638 }
639 if (uio->uio_resid == 0 && controlp == NULL)
640 goto release;
641 if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
642 error = EWOULDBLOCK;
643 goto release;
644 }
645 SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1");
646 SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
647 sbunlock(&so->so_rcv);
648 error = sbwait(&so->so_rcv);
649 splx(s);
650 if (error)
651 return (error);
652 goto restart;
653 }
654 dontblock:
655
656
657
658
659
660 if (uio->uio_procp)
661 uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
662 KASSERT(m == so->so_rcv.sb_mb);
663 SBLASTRECORDCHK(&so->so_rcv, "soreceive 1");
664 SBLASTMBUFCHK(&so->so_rcv, "soreceive 1");
665 nextrecord = m->m_nextpkt;
666 if (pr->pr_flags & PR_ADDR) {
667 #ifdef DIAGNOSTIC
668 if (m->m_type != MT_SONAME)
669 panic("receive 1a");
670 #endif
671 orig_resid = 0;
672 if (flags & MSG_PEEK) {
673 if (paddr)
674 *paddr = m_copy(m, 0, m->m_len);
675 m = m->m_next;
676 } else {
677 sbfree(&so->so_rcv, m);
678 if (paddr) {
679 *paddr = m;
680 so->so_rcv.sb_mb = m->m_next;
681 m->m_next = 0;
682 m = so->so_rcv.sb_mb;
683 } else {
684 MFREE(m, so->so_rcv.sb_mb);
685 m = so->so_rcv.sb_mb;
686 }
687 }
688 }
689 while (m && m->m_type == MT_CONTROL && error == 0) {
690 if (flags & MSG_PEEK) {
691 if (controlp)
692 *controlp = m_copy(m, 0, m->m_len);
693 m = m->m_next;
694 } else {
695 sbfree(&so->so_rcv, m);
696 if (controlp) {
697 if (pr->pr_domain->dom_externalize &&
698 mtod(m, struct cmsghdr *)->cmsg_type ==
699 SCM_RIGHTS)
700 error = (*pr->pr_domain->dom_externalize)(m);
701 *controlp = m;
702 so->so_rcv.sb_mb = m->m_next;
703 m->m_next = 0;
704 m = so->so_rcv.sb_mb;
705 } else {
706
707
708
709
710 if (pr->pr_domain->dom_dispose &&
711 mtod(m, struct cmsghdr *)->cmsg_type == SCM_RIGHTS)
712 pr->pr_domain->dom_dispose(m);
713 MFREE(m, so->so_rcv.sb_mb);
714 m = so->so_rcv.sb_mb;
715 }
716 }
717 if (controlp) {
718 orig_resid = 0;
719 controlp = &(*controlp)->m_next;
720 }
721 }
722
723
724
725
726
727
728
729 if (m) {
730 if ((flags & MSG_PEEK) == 0) {
731 m->m_nextpkt = nextrecord;
732
733
734
735
736
737 if (nextrecord == NULL) {
738 KASSERT(so->so_rcv.sb_mb == m);
739 so->so_rcv.sb_lastrecord = m;
740 }
741 }
742 type = m->m_type;
743 if (type == MT_OOBDATA)
744 flags |= MSG_OOB;
745 if (m->m_flags & M_BCAST)
746 flags |= MSG_BCAST;
747 if (m->m_flags & M_MCAST)
748 flags |= MSG_MCAST;
749 } else {
750 if ((flags & MSG_PEEK) == 0) {
751 KASSERT(so->so_rcv.sb_mb == m);
752 so->so_rcv.sb_mb = nextrecord;
753 SB_EMPTY_FIXUP(&so->so_rcv);
754 }
755 }
756 SBLASTRECORDCHK(&so->so_rcv, "soreceive 2");
757 SBLASTMBUFCHK(&so->so_rcv, "soreceive 2");
758
759 moff = 0;
760 offset = 0;
761 while (m && uio->uio_resid > 0 && error == 0) {
762 if (m->m_type == MT_OOBDATA) {
763 if (type != MT_OOBDATA)
764 break;
765 } else if (type == MT_OOBDATA)
766 break;
767 #ifdef DIAGNOSTIC
768 else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
769 panic("receive 3");
770 #endif
771 so->so_state &= ~SS_RCVATMARK;
772 len = uio->uio_resid;
773 if (so->so_oobmark && len > so->so_oobmark - offset)
774 len = so->so_oobmark - offset;
775 if (len > m->m_len - moff)
776 len = m->m_len - moff;
777
778
779
780
781
782
783
784
785 if (mp == NULL && uio_error == 0) {
786 SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
787 SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
788 resid = uio->uio_resid;
789 splx(s);
790 uio_error =
791 uiomove(mtod(m, caddr_t) + moff, (int)len,
792 uio);
793 s = splsoftnet();
794 if (uio_error)
795 uio->uio_resid = resid - len;
796 } else
797 uio->uio_resid -= len;
798 if (len == m->m_len - moff) {
799 if (m->m_flags & M_EOR)
800 flags |= MSG_EOR;
801 if (flags & MSG_PEEK) {
802 m = m->m_next;
803 moff = 0;
804 } else {
805 nextrecord = m->m_nextpkt;
806 sbfree(&so->so_rcv, m);
807 if (mp) {
808 *mp = m;
809 mp = &m->m_next;
810 so->so_rcv.sb_mb = m = m->m_next;
811 *mp = NULL;
812 } else {
813 MFREE(m, so->so_rcv.sb_mb);
814 m = so->so_rcv.sb_mb;
815 }
816
817
818
819
820 KASSERT(so->so_rcv.sb_mb == m);
821 if (m) {
822 m->m_nextpkt = nextrecord;
823 if (nextrecord == NULL)
824 so->so_rcv.sb_lastrecord = m;
825 } else {
826 so->so_rcv.sb_mb = nextrecord;
827 SB_EMPTY_FIXUP(&so->so_rcv);
828 }
829 SBLASTRECORDCHK(&so->so_rcv, "soreceive 3");
830 SBLASTMBUFCHK(&so->so_rcv, "soreceive 3");
831 }
832 } else {
833 if (flags & MSG_PEEK)
834 moff += len;
835 else {
836 if (mp)
837 *mp = m_copym(m, 0, len, M_WAIT);
838 m->m_data += len;
839 m->m_len -= len;
840 so->so_rcv.sb_cc -= len;
841 so->so_rcv.sb_datacc -= len;
842 }
843 }
844 if (so->so_oobmark) {
845 if ((flags & MSG_PEEK) == 0) {
846 so->so_oobmark -= len;
847 if (so->so_oobmark == 0) {
848 so->so_state |= SS_RCVATMARK;
849 break;
850 }
851 } else {
852 offset += len;
853 if (offset == so->so_oobmark)
854 break;
855 }
856 }
857 if (flags & MSG_EOR)
858 break;
859
860
861
862
863
864
865
866 while (flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 &&
867 !sosendallatonce(so) && !nextrecord) {
868 if (so->so_error || so->so_state & SS_CANTRCVMORE)
869 break;
870 SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
871 SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
872 error = sbwait(&so->so_rcv);
873 if (error) {
874 sbunlock(&so->so_rcv);
875 splx(s);
876 return (0);
877 }
878 if ((m = so->so_rcv.sb_mb) != NULL)
879 nextrecord = m->m_nextpkt;
880 }
881 }
882
883 if (m && pr->pr_flags & PR_ATOMIC) {
884 flags |= MSG_TRUNC;
885 if ((flags & MSG_PEEK) == 0)
886 (void) sbdroprecord(&so->so_rcv);
887 }
888 if ((flags & MSG_PEEK) == 0) {
889 if (m == NULL) {
890
891
892
893
894
895 so->so_rcv.sb_mb = nextrecord;
896 if (so->so_rcv.sb_mb == NULL) {
897 so->so_rcv.sb_mbtail = NULL;
898 so->so_rcv.sb_lastrecord = NULL;
899 } else if (nextrecord->m_nextpkt == NULL)
900 so->so_rcv.sb_lastrecord = nextrecord;
901 }
902 SBLASTRECORDCHK(&so->so_rcv, "soreceive 4");
903 SBLASTMBUFCHK(&so->so_rcv, "soreceive 4");
904 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
905 (*pr->pr_usrreq)(so, PRU_RCVD, NULL,
906 (struct mbuf *)(long)flags, NULL);
907 }
908 if (orig_resid == uio->uio_resid && orig_resid &&
909 (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
910 sbunlock(&so->so_rcv);
911 splx(s);
912 goto restart;
913 }
914
915 if (uio_error)
916 error = uio_error;
917
918 if (flagsp)
919 *flagsp |= flags;
920 release:
921 sbunlock(&so->so_rcv);
922 splx(s);
923 return (error);
924 }
925
926 int
927 soshutdown(struct socket *so, int how)
928 {
929 struct protosw *pr = so->so_proto;
930
931 switch (how) {
932 case SHUT_RD:
933 case SHUT_RDWR:
934 sorflush(so);
935 if (how == SHUT_RD)
936 return (0);
937
938 case SHUT_WR:
939 return (*pr->pr_usrreq)(so, PRU_SHUTDOWN, NULL, NULL, NULL);
940 default:
941 return (EINVAL);
942 }
943 }
944
945 void
946 sorflush(struct socket *so)
947 {
948 struct sockbuf *sb = &so->so_rcv;
949 struct protosw *pr = so->so_proto;
950 int s;
951 struct sockbuf asb;
952
953 sb->sb_flags |= SB_NOINTR;
954 (void) sblock(sb, M_WAITOK);
955 s = splnet();
956 socantrcvmore(so);
957 sbunlock(sb);
958 asb = *sb;
959 bzero(sb, sizeof (*sb));
960
961 if (asb.sb_flags & SB_KNOTE) {
962 sb->sb_sel.si_note = asb.sb_sel.si_note;
963 sb->sb_flags = SB_KNOTE;
964 }
965 splx(s);
966 if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
967 (*pr->pr_domain->dom_dispose)(asb.sb_mb);
968 sbrelease(&asb);
969 }
970
971 int
972 sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
973 {
974 int error = 0;
975 struct mbuf *m = m0;
976
977 if (level != SOL_SOCKET) {
978 if (so->so_proto && so->so_proto->pr_ctloutput)
979 return ((*so->so_proto->pr_ctloutput)
980 (PRCO_SETOPT, so, level, optname, &m0));
981 error = ENOPROTOOPT;
982 } else {
983 switch (optname) {
984
985 case SO_LINGER:
986 if (m == NULL || m->m_len != sizeof (struct linger) ||
987 mtod(m, struct linger *)->l_linger < 0 ||
988 mtod(m, struct linger *)->l_linger > SHRT_MAX) {
989 error = EINVAL;
990 goto bad;
991 }
992 so->so_linger = mtod(m, struct linger *)->l_linger;
993
994
995 case SO_DEBUG:
996 case SO_KEEPALIVE:
997 case SO_DONTROUTE:
998 case SO_USELOOPBACK:
999 case SO_BROADCAST:
1000 case SO_REUSEADDR:
1001 case SO_REUSEPORT:
1002 case SO_OOBINLINE:
1003 case SO_JUMBO:
1004 if (m == NULL || m->m_len < sizeof (int)) {
1005 error = EINVAL;
1006 goto bad;
1007 }
1008 if (*mtod(m, int *))
1009 so->so_options |= optname;
1010 else
1011 so->so_options &= ~optname;
1012 break;
1013
1014 case SO_SNDBUF:
1015 case SO_RCVBUF:
1016 case SO_SNDLOWAT:
1017 case SO_RCVLOWAT:
1018 {
1019 u_long cnt;
1020
1021 if (m == NULL || m->m_len < sizeof (int)) {
1022 error = EINVAL;
1023 goto bad;
1024 }
1025 cnt = *mtod(m, int *);
1026 if ((long)cnt <= 0)
1027 cnt = 1;
1028 switch (optname) {
1029
1030 case SO_SNDBUF:
1031 if (sbcheckreserve(cnt, so->so_snd.sb_hiwat) ||
1032 sbreserve(&so->so_snd, cnt) == 0) {
1033 error = ENOBUFS;
1034 goto bad;
1035 }
1036 break;
1037
1038 case SO_RCVBUF:
1039 if (sbcheckreserve(cnt, so->so_rcv.sb_hiwat) ||
1040 sbreserve(&so->so_rcv, cnt) == 0) {
1041 error = ENOBUFS;
1042 goto bad;
1043 }
1044 break;
1045
1046 case SO_SNDLOWAT:
1047 so->so_snd.sb_lowat = (cnt > so->so_snd.sb_hiwat) ?
1048 so->so_snd.sb_hiwat : cnt;
1049 break;
1050 case SO_RCVLOWAT:
1051 so->so_rcv.sb_lowat = (cnt > so->so_rcv.sb_hiwat) ?
1052 so->so_rcv.sb_hiwat : cnt;
1053 break;
1054 }
1055 break;
1056 }
1057
1058 case SO_SNDTIMEO:
1059 case SO_RCVTIMEO:
1060 {
1061 struct timeval *tv;
1062 short val;
1063
1064 if (m == NULL || m->m_len < sizeof (*tv)) {
1065 error = EINVAL;
1066 goto bad;
1067 }
1068 tv = mtod(m, struct timeval *);
1069 if (tv->tv_sec > (SHRT_MAX - tv->tv_usec / tick) / hz) {
1070 error = EDOM;
1071 goto bad;
1072 }
1073 val = tv->tv_sec * hz + tv->tv_usec / tick;
1074 if (val == 0 && tv->tv_usec != 0)
1075 val = 1;
1076
1077 switch (optname) {
1078
1079 case SO_SNDTIMEO:
1080 so->so_snd.sb_timeo = val;
1081 break;
1082 case SO_RCVTIMEO:
1083 so->so_rcv.sb_timeo = val;
1084 break;
1085 }
1086 break;
1087 }
1088
1089 default:
1090 error = ENOPROTOOPT;
1091 break;
1092 }
1093 if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
1094 (void) ((*so->so_proto->pr_ctloutput)
1095 (PRCO_SETOPT, so, level, optname, &m0));
1096 m = NULL;
1097 }
1098 }
1099 bad:
1100 if (m)
1101 (void) m_free(m);
1102 return (error);
1103 }
1104
1105 int
1106 sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
1107 {
1108 struct mbuf *m;
1109
1110 if (level != SOL_SOCKET) {
1111 if (so->so_proto && so->so_proto->pr_ctloutput) {
1112 return ((*so->so_proto->pr_ctloutput)
1113 (PRCO_GETOPT, so, level, optname, mp));
1114 } else
1115 return (ENOPROTOOPT);
1116 } else {
1117 m = m_get(M_WAIT, MT_SOOPTS);
1118 m->m_len = sizeof (int);
1119
1120 switch (optname) {
1121
1122 case SO_LINGER:
1123 m->m_len = sizeof (struct linger);
1124 mtod(m, struct linger *)->l_onoff =
1125 so->so_options & SO_LINGER;
1126 mtod(m, struct linger *)->l_linger = so->so_linger;
1127 break;
1128
1129 case SO_USELOOPBACK:
1130 case SO_DONTROUTE:
1131 case SO_DEBUG:
1132 case SO_KEEPALIVE:
1133 case SO_REUSEADDR:
1134 case SO_REUSEPORT:
1135 case SO_BROADCAST:
1136 case SO_OOBINLINE:
1137 case SO_JUMBO:
1138 *mtod(m, int *) = so->so_options & optname;
1139 break;
1140
1141 case SO_TYPE:
1142 *mtod(m, int *) = so->so_type;
1143 break;
1144
1145 case SO_ERROR:
1146 *mtod(m, int *) = so->so_error;
1147 so->so_error = 0;
1148 break;
1149
1150 case SO_SNDBUF:
1151 *mtod(m, int *) = so->so_snd.sb_hiwat;
1152 break;
1153
1154 case SO_RCVBUF:
1155 *mtod(m, int *) = so->so_rcv.sb_hiwat;
1156 break;
1157
1158 case SO_SNDLOWAT:
1159 *mtod(m, int *) = so->so_snd.sb_lowat;
1160 break;
1161
1162 case SO_RCVLOWAT:
1163 *mtod(m, int *) = so->so_rcv.sb_lowat;
1164 break;
1165
1166 case SO_SNDTIMEO:
1167 case SO_RCVTIMEO:
1168 {
1169 int val = (optname == SO_SNDTIMEO ?
1170 so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
1171
1172 m->m_len = sizeof(struct timeval);
1173 mtod(m, struct timeval *)->tv_sec = val / hz;
1174 mtod(m, struct timeval *)->tv_usec =
1175 (val % hz) * tick;
1176 break;
1177 }
1178
1179 default:
1180 (void)m_free(m);
1181 return (ENOPROTOOPT);
1182 }
1183 *mp = m;
1184 return (0);
1185 }
1186 }
1187
1188 void
1189 sohasoutofband(struct socket *so)
1190 {
1191 csignal(so->so_pgid, SIGURG, so->so_siguid, so->so_sigeuid);
1192 selwakeup(&so->so_rcv.sb_sel);
1193 }
1194
1195 int
1196 soo_kqfilter(struct file *fp, struct knote *kn)
1197 {
1198 struct socket *so = (struct socket *)kn->kn_fp->f_data;
1199 struct sockbuf *sb;
1200 int s;
1201
1202 switch (kn->kn_filter) {
1203 case EVFILT_READ:
1204 if (so->so_options & SO_ACCEPTCONN)
1205 kn->kn_fop = &solisten_filtops;
1206 else
1207 kn->kn_fop = &soread_filtops;
1208 sb = &so->so_rcv;
1209 break;
1210 case EVFILT_WRITE:
1211 kn->kn_fop = &sowrite_filtops;
1212 sb = &so->so_snd;
1213 break;
1214 default:
1215 return (1);
1216 }
1217
1218 s = splnet();
1219 SLIST_INSERT_HEAD(&sb->sb_sel.si_note, kn, kn_selnext);
1220 sb->sb_flags |= SB_KNOTE;
1221 splx(s);
1222 return (0);
1223 }
1224
1225 void
1226 filt_sordetach(struct knote *kn)
1227 {
1228 struct socket *so = (struct socket *)kn->kn_fp->f_data;
1229 int s = splnet();
1230
1231 SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext);
1232 if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note))
1233 so->so_rcv.sb_flags &= ~SB_KNOTE;
1234 splx(s);
1235 }
1236
1237
1238 int
1239 filt_soread(struct knote *kn, long hint)
1240 {
1241 struct socket *so = (struct socket *)kn->kn_fp->f_data;
1242
1243 kn->kn_data = so->so_rcv.sb_cc;
1244 if (so->so_state & SS_CANTRCVMORE) {
1245 kn->kn_flags |= EV_EOF;
1246 kn->kn_fflags = so->so_error;
1247 return (1);
1248 }
1249 if (so->so_error)
1250 return (1);
1251 if (kn->kn_sfflags & NOTE_LOWAT)
1252 return (kn->kn_data >= kn->kn_sdata);
1253 return (kn->kn_data >= so->so_rcv.sb_lowat);
1254 }
1255
1256 void
1257 filt_sowdetach(struct knote *kn)
1258 {
1259 struct socket *so = (struct socket *)kn->kn_fp->f_data;
1260 int s = splnet();
1261
1262 SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext);
1263 if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note))
1264 so->so_snd.sb_flags &= ~SB_KNOTE;
1265 splx(s);
1266 }
1267
1268
1269 int
1270 filt_sowrite(struct knote *kn, long hint)
1271 {
1272 struct socket *so = (struct socket *)kn->kn_fp->f_data;
1273
1274 kn->kn_data = sbspace(&so->so_snd);
1275 if (so->so_state & SS_CANTSENDMORE) {
1276 kn->kn_flags |= EV_EOF;
1277 kn->kn_fflags = so->so_error;
1278 return (1);
1279 }
1280 if (so->so_error)
1281 return (1);
1282 if (((so->so_state & SS_ISCONNECTED) == 0) &&
1283 (so->so_proto->pr_flags & PR_CONNREQUIRED))
1284 return (0);
1285 if (kn->kn_sfflags & NOTE_LOWAT)
1286 return (kn->kn_data >= kn->kn_sdata);
1287 return (kn->kn_data >= so->so_snd.sb_lowat);
1288 }
1289
1290
1291 int
1292 filt_solisten(struct knote *kn, long hint)
1293 {
1294 struct socket *so = (struct socket *)kn->kn_fp->f_data;
1295
1296 kn->kn_data = so->so_qlen;
1297 return (so->so_qlen != 0);
1298 }