105#include <sys/cdefs.h>
109#include "opt_inet6.h"
110#include "opt_kern_tls.h"
113#include <sys/param.h>
114#include <sys/systm.h>
115#include <sys/capsicum.h>
116#include <sys/fcntl.h>
117#include <sys/limits.h>
120#include <sys/malloc.h>
122#include <sys/mutex.h>
123#include <sys/domain.h>
125#include <sys/hhook.h>
126#include <sys/kernel.h>
127#include <sys/khelp.h>
129#include <sys/event.h>
130#include <sys/eventhandler.h>
133#include <sys/protosw.h>
135#include <sys/socket.h>
136#include <sys/socketvar.h>
137#include <sys/resourcevar.h>
138#include <net/route.h>
139#include <sys/signalvar.h>
142#include <sys/sysctl.h>
143#include <sys/taskqueue.h>
146#include <sys/unpcb.h>
148#include <sys/syslog.h>
149#include <netinet/in.h>
150#include <netinet/in_pcb.h>
151#include <netinet/tcp.h>
155#include <security/mac/mac_framework.h>
159#ifdef COMPAT_FREEBSD32
160#include <sys/mount.h>
161#include <sys/sysent.h>
162#include <compat/freebsd32/freebsd32.h>
179static int inline hhook_run_socket(
struct socket *so,
void *hctx, int32_t h_id);
203#define VNET_SO_ASSERT(so) \
204 VNET_ASSERT(curvnet != NULL, \
205 ("%s:%d curvnet is NULL, so=%p", __func__, __LINE__, (so)));
207VNET_DEFINE(
struct hhook_head *, socket_hhh[HHOOK_SOCKET_LAST + 1]);
208#define V_socket_hhh VNET(socket_hhh)
226 if (error || !req->newptr )
235 if (val < 1 || val > UINT_MAX / 3)
242 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
sizeof(
int),
244 "Maximum listen socket pending connection accept queue size");
246 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_SKIP | CTLFLAG_MPSAFE, 0,
248 "Maximum listen socket pending connection accept queue size (compat)");
295 HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0)
296 printf(
"%s: WARNING: unable to register hook\n", __func__);
304 printf(
"%s: WARNING: unable to deregister hook\n", __func__);
311 socket_zone = uma_zcreate(
"socket",
sizeof(
struct socket), NULL, NULL,
312 NULL, NULL, UMA_ALIGN_PTR, 0);
314 uma_zone_set_warning(
socket_zone,
"kern.ipc.maxsockets limit reached");
316 EVENTHANDLER_PRI_FIRST);
326 for (i = 0; i <= HHOOK_SOCKET_LAST; i++)
337 for (i = 0; i <= HHOOK_SOCKET_LAST; i++)
351 TUNABLE_INT_FETCH(
"kern.ipc.maxsockets", &
maxsockets);
363 int error, newmaxsockets;
367 if (error == 0 && req->newptr && newmaxsockets !=
maxsockets) {
371 EVENTHANDLER_INVOKE(maxsockets_change);
378 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &
maxsockets, 0,
380 "Maximum number of sockets available");
396static struct socket *
405 if (mac_socket_init(so, M_NOWAIT) != 0) {
420 mtx_init(&so->so_lock,
"socket", NULL, MTX_DEF | MTX_DUPOK);
421 so->so_snd.sb_mtx = &so->so_snd_mtx;
422 so->so_rcv.sb_mtx = &so->so_rcv_mtx;
423 SOCKBUF_LOCK_INIT(&so->so_snd,
"so_snd");
424 SOCKBUF_LOCK_INIT(&so->so_rcv,
"so_rcv");
425 so->so_rcv.sb_sel = &so->so_rdsel;
426 so->so_snd.sb_sel = &so->so_wrsel;
427 sx_init(&so->so_snd_sx,
"so_snd_sx");
428 sx_init(&so->so_rcv_sx,
"so_rcv_sx");
429 TAILQ_INIT(&so->so_snd.sb_aiojobq);
430 TAILQ_INIT(&so->so_rcv.sb_aiojobq);
431 TASK_INIT(&so->so_snd.sb_aiotask, 0,
soaio_snd, so);
432 TASK_INIT(&so->so_rcv.sb_aiotask, 0,
soaio_rcv, so);
434 VNET_ASSERT(vnet != NULL, (
"%s:%d vnet is NULL, so=%p",
435 __func__, __LINE__, so));
448 vnet->vnet_sockcnt++;
464 KASSERT(so->so_count == 0, (
"sodealloc(): so_count %d", so->so_count));
465 KASSERT(so->so_pcb == NULL, (
"sodealloc(): so_pcb != NULL"));
471 VNET_ASSERT(so->so_vnet != NULL, (
"%s:%d so_vnet is NULL, so=%p",
472 __func__, __LINE__, so));
473 so->so_vnet->vnet_sockcnt--;
477 mac_socket_destroy(so);
482 if (SOLISTENING(so)) {
483 if (so->sol_accept_filter != NULL)
486 if (so->so_rcv.sb_hiwat)
488 &so->so_rcv.sb_hiwat, 0, RLIM_INFINITY);
489 if (so->so_snd.sb_hiwat)
491 &so->so_snd.sb_hiwat, 0, RLIM_INFINITY);
494 SOCKBUF_LOCK_DESTROY(&so->so_snd);
495 SOCKBUF_LOCK_DESTROY(&so->so_rcv);
498 mtx_destroy(&so->so_lock);
508 struct ucred *cred,
struct thread *td)
522 return (EAFNOSUPPORT);
524 if (proto == 0 &&
type != 0)
526 return (EPROTONOSUPPORT);
528 if (prp->pr_usrreqs->pru_attach == NULL ||
530 return (EPROTONOSUPPORT);
532 if (IN_CAPABILITY_MODE(td) && (prp->pr_flags & PR_CAPATTACH) == 0)
536 return (EPROTONOSUPPORT);
538 if (prp->pr_type !=
type)
540 so =
soalloc(CRED_TO_VNET(cred));
545 so->so_cred =
crhold(cred);
546 if ((prp->pr_domain->dom_family == PF_INET) ||
547 (prp->pr_domain->dom_family == PF_INET6) ||
548 (prp->pr_domain->dom_family == PF_ROUTE))
549 so->so_fibnum = td->td_proc->p_fibnum;
554 mac_socket_create(cred, so);
564 CURVNET_SET(so->so_vnet);
565 error = (*prp->pr_usrreqs->pru_attach)(so, proto, td);
577static int regression_sonewconn_earlytest = 1;
578SYSCTL_INT(_regression, OID_AUTO, sonewconn_earlytest, CTLFLAG_RW,
579 ®ression_sonewconn_earlytest, 0,
"Perform early sonewconn limit test");
585 "Delay in seconds between warnings for listen socket overflows");
603 const char localprefix[] =
"local:";
604 char descrbuf[SUNPATHLEN +
sizeof(localprefix)];
606 char addrbuf[INET6_ADDRSTRLEN];
608 char addrbuf[INET_ADDRSTRLEN];
613 over = (head->sol_qlen > 3 * head->sol_qlimit / 2);
615 if (regression_sonewconn_earlytest && over) {
619 head->sol_overcount++;
628 overcount = head->sol_overcount;
629 head->sol_overcount = 0;
630 qlen = head->sol_qlen;
632 SOLISTEN_UNLOCK(head);
639 sbuf_new(&descrsb, descrbuf,
sizeof(descrbuf),
641 switch (head->so_proto->pr_domain->dom_family) {
642#if defined(INET) || defined(INET6)
648 if (head->so_proto->pr_domain->dom_family ==
650 (sotoinpcb(head)->inp_inc.inc_flags &
653 &sotoinpcb(head)->inp_inc.inc6_laddr);
660 sotoinpcb(head)->inp_inc.inc_laddr,
666 ntohs(sotoinpcb(head)->inp_inc.inc_lport),
667 head->so_proto->pr_protocol);
672 if (sotounpcb(head)->unp_addr != NULL)
674 sotounpcb(head)->unp_addr->sun_len -
675 offsetof(
struct sockaddr_un,
681 sotounpcb(head)->unp_addr->sun_path,
696 head->so_proto->pr_domain->dom_name ?:
701 (
"%s: sbuf creation failed", __func__));
703 "%s: pcb %p (%s): Listen queue overflow: "
704 "%i already in queue awaiting acceptance "
705 "(%d occurrences)\n",
706 __func__, head->so_pcb,
sbuf_data(&descrsb),
715 SOLISTEN_UNLOCK(head);
716 VNET_ASSERT(head->so_vnet != NULL, (
"%s: so %p vnet is NULL",
720 log(LOG_DEBUG,
"%s: pcb %p: New socket allocation failure: "
721 "limit reached or out of memory\n",
722 __func__, head->so_pcb);
725 so->so_listen = head;
726 so->so_type = head->so_type;
727 so->so_options = head->so_options & ~SO_ACCEPTCONN;
728 so->so_linger = head->so_linger;
729 so->so_state = head->so_state | SS_NOFDREF;
730 so->so_fibnum = head->so_fibnum;
731 so->so_proto = head->so_proto;
732 so->so_cred =
crhold(head->so_cred);
734 mac_socket_newconn(head, so);
741 if (
soreserve(so, head->sol_sbsnd_hiwat, head->sol_sbrcv_hiwat)) {
743 log(LOG_DEBUG,
"%s: pcb %p: soreserve() failed\n",
744 __func__, head->so_pcb);
747 if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) {
749 log(LOG_DEBUG,
"%s: pcb %p: pru_attach() failed\n",
750 __func__, head->so_pcb);
753 so->so_rcv.sb_lowat = head->sol_sbrcv_lowat;
754 so->so_snd.sb_lowat = head->sol_sbsnd_lowat;
755 so->so_rcv.sb_timeo = head->sol_sbrcv_timeo;
756 so->so_snd.sb_timeo = head->sol_sbsnd_timeo;
757 so->so_rcv.sb_flags |= head->sol_sbrcv_flags & SB_AUTOSIZE;
758 so->so_snd.sb_flags |= head->sol_sbsnd_flags & SB_AUTOSIZE;
761 if (head->sol_accept_filter != NULL)
763 so->so_state |= connstatus;
766 TAILQ_INSERT_TAIL(&head->sol_comp, so, so_list);
767 so->so_qstate = SQ_COMP;
778 while (head->sol_incqlen > head->sol_qlimit) {
781 sp = TAILQ_FIRST(&head->sol_incomp);
782 TAILQ_REMOVE(&head->sol_incomp, sp, so_list);
785 sp->so_qstate = SQ_NONE;
786 sp->so_listen = NULL;
792 TAILQ_INSERT_TAIL(&head->sol_incomp, so, so_list);
793 so->so_qstate = SQ_INCOMP;
795 SOLISTEN_UNLOCK(head);
800#if defined(SCTP) || defined(SCTP_SUPPORT)
806sopeeloff(
struct socket *head)
810 VNET_ASSERT(head->so_vnet != NULL, (
"%s:%d so_vnet is NULL, head=%p",
811 __func__, __LINE__, head));
814 log(LOG_DEBUG,
"%s: pcb %p: New socket allocation failure: "
815 "limit reached or out of memory\n",
816 __func__, head->so_pcb);
819 so->so_type = head->so_type;
820 so->so_options = head->so_options;
821 so->so_linger = head->so_linger;
822 so->so_state = (head->so_state & SS_NBIO) | SS_ISCONNECTED;
823 so->so_fibnum = head->so_fibnum;
824 so->so_proto = head->so_proto;
825 so->so_cred =
crhold(head->so_cred);
827 mac_socket_newconn(head, so);
834 if (
soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat)) {
836 log(LOG_DEBUG,
"%s: pcb %p: soreserve() failed\n",
837 __func__, head->so_pcb);
840 if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) {
842 log(LOG_DEBUG,
"%s: pcb %p: pru_attach() failed\n",
843 __func__, head->so_pcb);
846 so->so_rcv.sb_lowat = head->so_rcv.sb_lowat;
847 so->so_snd.sb_lowat = head->so_snd.sb_lowat;
848 so->so_rcv.sb_timeo = head->so_rcv.sb_timeo;
849 so->so_snd.sb_timeo = head->so_snd.sb_timeo;
850 so->so_rcv.sb_flags |= head->so_rcv.sb_flags & SB_AUTOSIZE;
851 so->so_snd.sb_flags |= head->so_snd.sb_flags & SB_AUTOSIZE;
860sobind(
struct socket *so,
struct sockaddr *nam,
struct thread *td)
864 CURVNET_SET(so->so_vnet);
865 error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam, td);
871sobindat(
int fd,
struct socket *so,
struct sockaddr *nam,
struct thread *td)
875 CURVNET_SET(so->so_vnet);
876 error = (*so->so_proto->pr_usrreqs->pru_bindat)(
fd, so, nam, td);
894solisten(
struct socket *so,
int backlog,
struct thread *td)
898 CURVNET_SET(so->so_vnet);
899 error = (*so->so_proto->pr_usrreqs->pru_listen)(so, backlog, td);
911 SOCK_LOCK_ASSERT(so);
913 if ((so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |
914 SS_ISDISCONNECTING)) != 0)
923 if (!sx_try_xlock(&so->so_snd_sx))
925 if (!sx_try_xlock(&so->so_rcv_sx)) {
926 sx_xunlock(&so->so_snd_sx);
929 mtx_lock(&so->so_snd_mtx);
930 mtx_lock(&so->so_rcv_mtx);
933 if ((so->so_snd.sb_flags & (SB_AIO | SB_AIO_RUNNING)) != 0 ||
934 (so->so_rcv.sb_flags & (SB_AIO | SB_AIO_RUNNING)) != 0) {
947 mtx_unlock(&so->so_snd_mtx);
948 mtx_unlock(&so->so_rcv_mtx);
949 sx_xunlock(&so->so_snd_sx);
950 sx_xunlock(&so->so_rcv_sx);
956 int sbrcv_lowat, sbsnd_lowat;
957 u_int sbrcv_hiwat, sbsnd_hiwat;
958 short sbrcv_flags, sbsnd_flags;
959 sbintime_t sbrcv_timeo, sbsnd_timeo;
961 SOCK_LOCK_ASSERT(so);
962 KASSERT((so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |
963 SS_ISDISCONNECTING)) == 0,
964 (
"%s: bad socket state %p", __func__, so));
972 sbrcv_lowat = so->so_rcv.sb_lowat;
973 sbsnd_lowat = so->so_snd.sb_lowat;
974 sbrcv_hiwat = so->so_rcv.sb_hiwat;
975 sbsnd_hiwat = so->so_snd.sb_hiwat;
976 sbrcv_flags = so->so_rcv.sb_flags;
977 sbsnd_flags = so->so_snd.sb_flags;
978 sbrcv_timeo = so->so_rcv.sb_timeo;
979 sbsnd_timeo = so->so_snd.sb_timeo;
986 sizeof(
struct socket) - offsetof(
struct socket, so_rcv));
989 so->sol_sbrcv_lowat = sbrcv_lowat;
990 so->sol_sbsnd_lowat = sbsnd_lowat;
991 so->sol_sbrcv_hiwat = sbrcv_hiwat;
992 so->sol_sbsnd_hiwat = sbsnd_hiwat;
993 so->sol_sbrcv_flags = sbrcv_flags;
994 so->sol_sbsnd_flags = sbsnd_flags;
995 so->sol_sbrcv_timeo = sbrcv_timeo;
996 so->sol_sbsnd_timeo = sbsnd_timeo;
998 so->sol_qlen = so->sol_incqlen = 0;
999 TAILQ_INIT(&so->sol_incomp);
1000 TAILQ_INIT(&so->sol_comp);
1002 so->sol_accept_filter = NULL;
1003 so->sol_accept_filter_arg = NULL;
1004 so->sol_accept_filter_str = NULL;
1006 so->sol_upcall = NULL;
1007 so->sol_upcallarg = NULL;
1009 so->so_options |= SO_ACCEPTCONN;
1014 so->sol_qlimit = backlog;
1016 mtx_unlock(&so->so_snd_mtx);
1017 mtx_unlock(&so->so_rcv_mtx);
1018 sx_xunlock(&so->so_snd_sx);
1019 sx_xunlock(&so->so_rcv_sx);
1030 if (sol->sol_upcall != NULL)
1031 (void )sol->sol_upcall(sol, sol->sol_upcallarg, M_NOWAIT);
1034 KNOTE_LOCKED(&sol->so_rdsel.si_note, 0);
1036 SOLISTEN_UNLOCK(sol);
1038 if ((sol->so_state & SS_ASYNC) && sol->so_sigio != NULL)
1039 pgsigio(&sol->so_sigio, SIGIO, 0);
1057 SOLISTEN_LOCK_ASSERT(head);
1059 while (!(head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->sol_comp) &&
1060 head->so_error == 0) {
1061 error = msleep(&head->sol_comp, SOCK_MTX(head), PSOCK | PCATCH,
1064 SOLISTEN_UNLOCK(head);
1068 if (head->so_error) {
1069 error = head->so_error;
1071 }
else if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->sol_comp))
1072 error = EWOULDBLOCK;
1076 SOLISTEN_UNLOCK(head);
1079 so = TAILQ_FIRST(&head->sol_comp);
1081 KASSERT(so->so_qstate == SQ_COMP,
1082 (
"%s: so %p not SQ_COMP", __func__, so));
1085 so->so_qstate = SQ_NONE;
1086 so->so_listen = NULL;
1087 TAILQ_REMOVE(&head->sol_comp, so, so_list);
1088 if (
flags & ACCEPT4_INHERIT)
1089 so->so_state |= (head->so_state & SS_NBIO);
1091 so->so_state |= (
flags & SOCK_NONBLOCK) ? SS_NBIO : 0;
1122 struct protosw *
pr = so->so_proto;
1123 bool last __diagused;
1125 SOCK_LOCK_ASSERT(so);
1127 if ((so->so_state & (SS_NOFDREF | SS_PROTOREF)) != SS_NOFDREF ||
1128 refcount_load(&so->so_count) != 0 || so->so_qstate == SQ_COMP) {
1133 if (!SOLISTENING(so) && so->so_qstate == SQ_INCOMP) {
1136 sol = so->so_listen;
1137 KASSERT(sol, (
"%s: so %p on incomp of NULL", __func__, so));
1158 if (so->so_qstate == SQ_INCOMP) {
1159 KASSERT(so->so_listen == sol,
1160 (
"%s: so %p migrated out of sol %p",
1161 __func__, so, sol));
1162 TAILQ_REMOVE(&sol->sol_incomp, so, so_list);
1164 last = refcount_release(&sol->so_count);
1165 KASSERT(!last, (
"%s: released last reference for %p",
1167 so->so_qstate = SQ_NONE;
1168 so->so_listen = NULL;
1170 KASSERT(so->so_listen == NULL,
1171 (
"%s: so %p not on (in)comp with so_listen",
1174 KASSERT(refcount_load(&so->so_count) == 1,
1175 (
"%s: so %p count %u", __func__, so, so->so_count));
1178 if (SOLISTENING(so))
1179 so->so_error = ECONNABORTED;
1182 if (so->so_dtor != NULL)
1186 if (
pr->pr_flags & PR_RIGHTS &&
pr->pr_domain->dom_dispose != NULL)
1187 (*
pr->pr_domain->dom_dispose)(so);
1188 if (
pr->pr_usrreqs->pru_detach != NULL)
1189 (*
pr->pr_usrreqs->pru_detach)(so);
1205 if (!SOLISTENING(so)) {
1223 SOCK_LOCK_ASSERT(so);
1224 if (refcount_release(&so->so_count))
1241 struct accept_queue lqueue;
1243 bool listening, last __diagused;
1245 KASSERT(!(so->so_state & SS_NOFDREF), (
"soclose: SS_NOFDREF on enter"));
1247 CURVNET_SET(so->so_vnet);
1249 if (so->so_state & SS_ISCONNECTED) {
1250 if ((so->so_state & SS_ISDISCONNECTING) == 0) {
1253 if (error == ENOTCONN)
1259 if ((so->so_options & SO_LINGER) != 0 && so->so_linger != 0) {
1260 if ((so->so_state & SS_ISDISCONNECTING) &&
1261 (so->so_state & SS_NBIO))
1263 while (so->so_state & SS_ISCONNECTED) {
1264 error = tsleep(&so->so_timeo,
1265 PSOCK | PCATCH,
"soclos",
1266 so->so_linger *
hz);
1274 if (so->so_proto->pr_usrreqs->pru_close != NULL)
1275 (*so->so_proto->pr_usrreqs->pru_close)(so);
1278 if ((listening = SOLISTENING(so))) {
1281 TAILQ_INIT(&lqueue);
1282 TAILQ_SWAP(&lqueue, &so->sol_incomp, socket, so_list);
1283 TAILQ_CONCAT(&lqueue, &so->sol_comp, so_list);
1285 so->sol_qlen = so->sol_incqlen = 0;
1287 TAILQ_FOREACH(sp, &lqueue, so_list) {
1289 sp->so_qstate = SQ_NONE;
1290 sp->so_listen = NULL;
1292 last = refcount_release(&so->so_count);
1293 KASSERT(!last, (
"%s: released last reference for %p",
1297 KASSERT((so->so_state & SS_NOFDREF) == 0, (
"soclose: NOFDREF"));
1298 so->so_state |= SS_NOFDREF;
1301 struct socket *sp, *tsp;
1303 TAILQ_FOREACH_SAFE(sp, &lqueue, so_list, tsp) {
1305 if (refcount_load(&sp->so_count) == 0) {
1343 KASSERT(so->so_count == 0, (
"soabort: so_count"));
1344 KASSERT((so->so_state & SS_PROTOREF) == 0, (
"soabort: SS_PROTOREF"));
1345 KASSERT(so->so_state & SS_NOFDREF, (
"soabort: !SS_NOFDREF"));
1348 if (so->so_proto->pr_usrreqs->pru_abort != NULL)
1349 (*so->so_proto->pr_usrreqs->pru_abort)(so);
1360 KASSERT((so->so_state & SS_NOFDREF) != 0, (
"soaccept: !NOFDREF"));
1361 so->so_state &= ~SS_NOFDREF;
1364 CURVNET_SET(so->so_vnet);
1365 error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
1371soconnect(
struct socket *so,
struct sockaddr *nam,
struct thread *td)
1382 CURVNET_SET(so->so_vnet);
1388 if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
1389 ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
1398 if (
fd == AT_FDCWD) {
1399 error = (*so->so_proto->pr_usrreqs->pru_connect)(so,
1402 error = (*so->so_proto->pr_usrreqs->pru_connectat)(
fd,
1416 CURVNET_SET(so1->so_vnet);
1417 error = (*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2);
1427 if ((so->so_state & SS_ISCONNECTED) == 0)
1429 if (so->so_state & SS_ISDISCONNECTING)
1432 error = (*so->so_proto->pr_usrreqs->pru_disconnect)(so);
1438 struct mbuf *top,
struct mbuf *control,
int flags,
struct thread *td)
1442 int clen = 0, error, dontroute;
1444 KASSERT(so->so_type == SOCK_DGRAM, (
"sosend_dgram: !SOCK_DGRAM"));
1445 KASSERT(so->so_proto->pr_flags & PR_ATOMIC,
1446 (
"sosend_dgram: !PR_ATOMIC"));
1449 resid = uio->uio_resid;
1451 resid = top->m_pkthdr.len;
1465 (
flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0;
1467 td->td_ru.ru_msgsnd++;
1468 if (control != NULL)
1469 clen = control->m_len;
1471 SOCKBUF_LOCK(&so->so_snd);
1472 if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
1473 SOCKBUF_UNLOCK(&so->so_snd);
1478 error = so->so_error;
1480 SOCKBUF_UNLOCK(&so->so_snd);
1483 if ((so->so_state & SS_ISCONNECTED) == 0) {
1489 if ((so->so_proto->pr_flags & PR_CONNREQUIRED) &&
1490 (so->so_proto->pr_flags & PR_IMPLOPCL) == 0) {
1491 if ((so->so_state & SS_ISCONFIRMING) == 0 &&
1492 !(resid == 0 && clen != 0)) {
1493 SOCKBUF_UNLOCK(&so->so_snd);
1497 }
else if (
addr == NULL) {
1498 if (so->so_proto->pr_flags & PR_CONNREQUIRED)
1501 error = EDESTADDRREQ;
1502 SOCKBUF_UNLOCK(&so->so_snd);
1511 space = sbspace(&so->so_snd);
1512 if (
flags & MSG_OOB)
1515 SOCKBUF_UNLOCK(&so->so_snd);
1516 if (resid > space) {
1522 if (
flags & MSG_EOR)
1523 top->m_flags |= M_EOR;
1531 (M_PKTHDR | ((
flags & MSG_EOR) ? M_EOR : 0)));
1536 space -= resid - uio->uio_resid;
1537 resid = uio->uio_resid;
1539 KASSERT(resid == 0, (
"sosend_dgram: resid != 0"));
1546 so->so_options |= SO_DONTROUTE;
1558 error = (*so->so_proto->pr_usrreqs->pru_send)(so,
1559 (
flags & MSG_OOB) ? PRUS_OOB :
1564 ((
flags & MSG_EOF) &&
1565 (so->so_proto->pr_flags & PR_IMPLOPCL) &&
1569 (
flags & MSG_MORETOCOME) ||
1570 (resid > 0 && space > 0) ? PRUS_MORETOCOME : 0,
1571 top,
addr, control, td);
1574 so->so_options &= ~SO_DONTROUTE;
1583 if (control != NULL)
1603 struct mbuf *top,
struct mbuf *control,
int flags,
struct thread *td)
1607 int clen = 0, error, dontroute;
1608 int atomic = sosendallatonce(so) || top;
1611 struct ktls_session *tls;
1612 int tls_enq_cnt, tls_pruflag;
1616 tls_rtype = TLS_RLTYPE_APP;
1619 resid = uio->uio_resid;
1620 else if ((top->m_flags & M_PKTHDR) != 0)
1621 resid = top->m_pkthdr.len;
1634 if (resid < 0 || (so->so_type == SOCK_STREAM && (
flags & MSG_EOR))) {
1640 (
flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
1641 (so->so_proto->pr_flags & PR_ATOMIC);
1643 td->td_ru.ru_msgsnd++;
1644 if (control != NULL)
1645 clen = control->m_len;
1647 error = SOCK_IO_SEND_LOCK(so, SBLOCKWAIT(
flags));
1653 tls = ktls_hold(so->so_snd.sb_tls_info);
1655 if (tls->mode == TCP_TLS_MODE_SW)
1656 tls_pruflag = PRUS_NOTREADY;
1658 if (control != NULL) {
1659 struct cmsghdr *cm = mtod(control,
struct cmsghdr *);
1661 if (clen >=
sizeof(*cm) &&
1662 cm->cmsg_type == TLS_SET_RECORD_TYPE) {
1663 tls_rtype = *((uint8_t *)CMSG_DATA(cm));
1680 SOCKBUF_LOCK(&so->so_snd);
1681 if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
1682 SOCKBUF_UNLOCK(&so->so_snd);
1687 error = so->so_error;
1689 SOCKBUF_UNLOCK(&so->so_snd);
1692 if ((so->so_state & SS_ISCONNECTED) == 0) {
1699 if ((so->so_proto->pr_flags & PR_CONNREQUIRED) &&
1700 (so->so_proto->pr_flags & PR_IMPLOPCL) == 0) {
1701 if ((so->so_state & SS_ISCONFIRMING) == 0 &&
1702 !(resid == 0 && clen != 0)) {
1703 SOCKBUF_UNLOCK(&so->so_snd);
1707 }
else if (
addr == NULL) {
1708 SOCKBUF_UNLOCK(&so->so_snd);
1709 if (so->so_proto->pr_flags & PR_CONNREQUIRED)
1712 error = EDESTADDRREQ;
1716 space = sbspace(&so->so_snd);
1717 if (
flags & MSG_OOB)
1719 if ((atomic && resid > so->so_snd.sb_hiwat) ||
1720 clen > so->so_snd.sb_hiwat) {
1721 SOCKBUF_UNLOCK(&so->so_snd);
1725 if (space < resid + clen &&
1726 (atomic || space < so->so_snd.sb_lowat || space < clen)) {
1727 if ((so->so_state & SS_NBIO) ||
1728 (
flags & (MSG_NBIO | MSG_DONTWAIT)) != 0) {
1729 SOCKBUF_UNLOCK(&so->so_snd);
1730 error = EWOULDBLOCK;
1733 error =
sbwait(&so->so_snd);
1734 SOCKBUF_UNLOCK(&so->so_snd);
1739 SOCKBUF_UNLOCK(&so->so_snd);
1744 if (
flags & MSG_EOR)
1745 top->m_flags |= M_EOR;
1750 tls_rtype = TLS_RLTYPE_APP;
1765 tls->params.max_frame_len,
1767 ((
flags & MSG_EOR) ? M_EOR : 0));
1770 &tls_enq_cnt, tls_rtype);
1772 tls_rtype = TLS_RLTYPE_APP;
1777 (atomic ? M_PKTHDR : 0) |
1778 ((
flags & MSG_EOR) ? M_EOR : 0));
1783 space -= resid - uio->uio_resid;
1784 resid = uio->uio_resid;
1788 so->so_options |= SO_DONTROUTE;
1803 pru_flag = (
flags & MSG_OOB) ? PRUS_OOB :
1809 ((
flags & MSG_EOF) &&
1810 (so->so_proto->pr_flags & PR_IMPLOPCL) &&
1814 (
flags & MSG_MORETOCOME) ||
1815 (resid > 0 && space > 0) ? PRUS_MORETOCOME : 0;
1818 pru_flag |= tls_pruflag;
1821 error = (*so->so_proto->pr_usrreqs->pru_send)(so,
1822 pru_flag, top,
addr, control, td);
1826 so->so_options &= ~SO_DONTROUTE;
1831 if (tls != NULL && tls->mode == TCP_TLS_MODE_SW) {
1846 }
while (resid && space > 0);
1850 SOCK_IO_SEND_UNLOCK(so);
1858 if (control != NULL)
1865 struct mbuf *top,
struct mbuf *control,
int flags,
struct thread *td)
1869 CURVNET_SET(so->so_vnet);
1870 error = so->so_proto->pr_usrreqs->pru_sosend(so,
addr, uio,
1871 top, control,
flags, td);
1887 struct protosw *
pr = so->so_proto;
1891 KASSERT(
flags & MSG_OOB, (
"soreceive_rcvoob: (flags & MSG_OOB) == 0"));
1894 m = m_get(M_WAITOK, MT_DATA);
1895 error = (*
pr->pr_usrreqs->pru_rcvoob)(so, m,
flags & MSG_PEEK);
1899 error =
uiomove(mtod(m,
void *),
1900 (
int) min(uio->uio_resid, m->m_len), uio);
1902 }
while (uio->uio_resid && error == 0 && m);
1921 SOCKBUF_LOCK_ASSERT(sb);
1926 if (sb->sb_mb != NULL)
1927 sb->sb_mb->m_nextpkt = nextrecord;
1929 sb->sb_mb = nextrecord;
1937 if (sb->sb_mb == NULL) {
1938 sb->sb_mbtail = NULL;
1939 sb->sb_lastrecord = NULL;
1940 }
else if (sb->sb_mb->m_nextpkt == NULL)
1941 sb->sb_lastrecord = sb->sb_mb;
1962 struct mbuf **mp0,
struct mbuf **controlp,
int *flagsp)
1964 struct mbuf *m, **mp;
1965 int flags, error, offset;
1967 struct protosw *
pr = so->so_proto;
1968 struct mbuf *nextrecord;
1970 ssize_t orig_resid = uio->uio_resid;
1975 if (controlp != NULL)
1978 flags = *flagsp &~ MSG_EOR;
1981 if (
flags & MSG_OOB)
1985 if ((
pr->pr_flags & PR_WANTRCVD) && (so->so_state & SS_ISCONFIRMING)
1986 && uio->uio_resid) {
1988 (*
pr->pr_usrreqs->pru_rcvd)(so, 0);
1991 error = SOCK_IO_RECV_LOCK(so, SBLOCKWAIT(
flags));
1996 SOCKBUF_LOCK(&so->so_rcv);
1997 m = so->so_rcv.sb_mb;
2004 if (m == NULL || (((
flags & MSG_DONTWAIT) == 0 &&
2005 sbavail(&so->so_rcv) < uio->uio_resid) &&
2006 sbavail(&so->so_rcv) < so->so_rcv.sb_lowat &&
2007 m->m_nextpkt == NULL && (
pr->pr_flags & PR_ATOMIC) == 0)) {
2008 KASSERT(m != NULL || !sbavail(&so->so_rcv),
2009 (
"receive: m == %p sbavail == %u",
2010 m, sbavail(&so->so_rcv)));
2011 if (so->so_error || so->so_rerror) {
2015 error = so->so_error;
2017 error = so->so_rerror;
2018 if ((
flags & MSG_PEEK) == 0) {
2024 SOCKBUF_UNLOCK(&so->so_rcv);
2027 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2028 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
2032 else if (so->so_rcv.sb_tlsdcc == 0 &&
2033 so->so_rcv.sb_tlscc == 0) {
2037 SOCKBUF_UNLOCK(&so->so_rcv);
2041 for (; m != NULL; m = m->m_next)
2042 if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) {
2043 m = so->so_rcv.sb_mb;
2046 if ((so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED |
2047 SS_ISDISCONNECTING | SS_ISDISCONNECTED)) == 0 &&
2048 (so->so_proto->pr_flags & PR_CONNREQUIRED) != 0) {
2049 SOCKBUF_UNLOCK(&so->so_rcv);
2053 if (uio->uio_resid == 0) {
2054 SOCKBUF_UNLOCK(&so->so_rcv);
2057 if ((so->so_state & SS_NBIO) ||
2058 (
flags & (MSG_DONTWAIT|MSG_NBIO))) {
2059 SOCKBUF_UNLOCK(&so->so_rcv);
2060 error = EWOULDBLOCK;
2063 SBLASTRECORDCHK(&so->so_rcv);
2064 SBLASTMBUFCHK(&so->so_rcv);
2065 error =
sbwait(&so->so_rcv);
2066 SOCKBUF_UNLOCK(&so->so_rcv);
2087 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2089 uio->uio_td->td_ru.ru_msgrcv++;
2090 KASSERT(m == so->so_rcv.sb_mb, (
"soreceive: m != so->so_rcv.sb_mb"));
2091 SBLASTRECORDCHK(&so->so_rcv);
2092 SBLASTMBUFCHK(&so->so_rcv);
2093 nextrecord = m->m_nextpkt;
2094 if (
pr->pr_flags & PR_ADDR) {
2095 KASSERT(m->m_type == MT_SONAME,
2096 (
"m->m_type == %d", m->m_type));
2101 if (
flags & MSG_PEEK) {
2105 so->so_rcv.sb_mb = m_free(m);
2106 m = so->so_rcv.sb_mb;
2117 if (m != NULL && m->m_type == MT_CONTROL) {
2118 struct mbuf *cm = NULL, *cmn;
2119 struct mbuf **cme = &cm;
2121 struct cmsghdr *cmsg;
2122 struct tls_get_record tgr;
2132 if (
flags & MSG_TLSAPPDATA) {
2133 cmsg = mtod(m,
struct cmsghdr *);
2134 if (cmsg->cmsg_type == TLS_GET_RECORD &&
2135 cmsg->cmsg_len == CMSG_LEN(
sizeof(tgr))) {
2136 memcpy(&tgr, CMSG_DATA(cmsg),
sizeof(tgr));
2138 if (tgr.tls_type != TLS_RLTYPE_APP) {
2139 SOCKBUF_UNLOCK(&so->so_rcv);
2148 if (
flags & MSG_PEEK) {
2149 if (controlp != NULL) {
2150 *controlp =
m_copym(m, 0, m->m_len,
2152 controlp = &(*controlp)->m_next;
2157 so->so_rcv.sb_mb = m->m_next;
2160 cme = &(*cme)->m_next;
2161 m = so->so_rcv.sb_mb;
2163 }
while (m != NULL && m->m_type == MT_CONTROL);
2164 if ((
flags & MSG_PEEK) == 0)
2166 while (cm != NULL) {
2169 if (
pr->pr_domain->dom_externalize != NULL) {
2170 SOCKBUF_UNLOCK(&so->so_rcv);
2172 error = (*
pr->pr_domain->dom_externalize)
2173 (cm, controlp,
flags);
2174 SOCKBUF_LOCK(&so->so_rcv);
2175 }
else if (controlp != NULL)
2179 if (controlp != NULL) {
2180 while (*controlp != NULL)
2181 controlp = &(*controlp)->m_next;
2186 nextrecord = so->so_rcv.sb_mb->m_nextpkt;
2188 nextrecord = so->so_rcv.sb_mb;
2192 if ((
flags & MSG_PEEK) == 0) {
2193 KASSERT(m->m_nextpkt == nextrecord,
2194 (
"soreceive: post-control, nextrecord !sync"));
2195 if (nextrecord == NULL) {
2196 KASSERT(so->so_rcv.sb_mb == m,
2197 (
"soreceive: post-control, sb_mb!=m"));
2198 KASSERT(so->so_rcv.sb_lastrecord == m,
2199 (
"soreceive: post-control, lastrecord!=m"));
2203 if (
type == MT_OOBDATA)
2206 if ((
flags & MSG_PEEK) == 0) {
2207 KASSERT(so->so_rcv.sb_mb == nextrecord,
2208 (
"soreceive: sb_mb != nextrecord"));
2209 if (so->so_rcv.sb_mb == NULL) {
2210 KASSERT(so->so_rcv.sb_lastrecord == NULL,
2211 (
"soreceive: sb_lastercord != NULL"));
2215 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2216 SBLASTRECORDCHK(&so->so_rcv);
2217 SBLASTMBUFCHK(&so->so_rcv);
2229 while (m != NULL && !(m->m_flags & M_NOTAVAIL) && uio->uio_resid > 0
2235 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2236 if (m->m_type == MT_OOBDATA || m->m_type == MT_CONTROL) {
2237 if (
type != m->m_type)
2239 }
else if (
type == MT_OOBDATA)
2242 KASSERT(m->m_type == MT_DATA,
2243 (
"m->m_type == %d", m->m_type));
2244 so->so_rcv.sb_state &= ~SBS_RCVATMARK;
2245 len = uio->uio_resid;
2246 if (so->so_oobmark && len > so->so_oobmark - offset)
2247 len = so->so_oobmark - offset;
2248 if (len > m->m_len - moff)
2249 len = m->m_len - moff;
2258 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2259 SBLASTRECORDCHK(&so->so_rcv);
2260 SBLASTMBUFCHK(&so->so_rcv);
2261 SOCKBUF_UNLOCK(&so->so_rcv);
2262 if ((m->m_flags & M_EXTPG) != 0)
2266 error =
uiomove(mtod(m,
char *) + moff,
2268 SOCKBUF_LOCK(&so->so_rcv);
2278 if (
pr->pr_flags & PR_ATOMIC &&
2279 ((
flags & MSG_PEEK) == 0))
2281 SOCKBUF_UNLOCK(&so->so_rcv);
2285 uio->uio_resid -= len;
2286 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2287 if (len == m->m_len - moff) {
2288 if (m->m_flags & M_EOR)
2290 if (
flags & MSG_PEEK) {
2294 nextrecord = m->m_nextpkt;
2297 m->m_nextpkt = NULL;
2300 so->so_rcv.sb_mb = m = m->m_next;
2303 so->so_rcv.sb_mb = m_free(m);
2304 m = so->so_rcv.sb_mb;
2307 SBLASTRECORDCHK(&so->so_rcv);
2308 SBLASTMBUFCHK(&so->so_rcv);
2311 if (
flags & MSG_PEEK)
2315 if (
flags & MSG_DONTWAIT) {
2328 uio->uio_resid += len;
2332 SOCKBUF_UNLOCK(&so->so_rcv);
2335 SOCKBUF_LOCK(&so->so_rcv);
2341 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2342 if (so->so_oobmark) {
2343 if ((
flags & MSG_PEEK) == 0) {
2344 so->so_oobmark -= len;
2345 if (so->so_oobmark == 0) {
2346 so->so_rcv.sb_state |= SBS_RCVATMARK;
2351 if (offset == so->so_oobmark)
2355 if (
flags & MSG_EOR)
2364 while (
flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 &&
2365 !sosendallatonce(so) && nextrecord == NULL) {
2366 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2367 if (so->so_error || so->so_rerror ||
2368 so->so_rcv.sb_state & SBS_CANTRCVMORE)
2374 if (
pr->pr_flags & PR_WANTRCVD) {
2375 SOCKBUF_UNLOCK(&so->so_rcv);
2377 (*
pr->pr_usrreqs->pru_rcvd)(so,
flags);
2378 SOCKBUF_LOCK(&so->so_rcv);
2380 SBLASTRECORDCHK(&so->so_rcv);
2381 SBLASTMBUFCHK(&so->so_rcv);
2386 if (so->so_rcv.sb_mb == NULL) {
2387 error =
sbwait(&so->so_rcv);
2389 SOCKBUF_UNLOCK(&so->so_rcv);
2393 m = so->so_rcv.sb_mb;
2395 nextrecord = m->m_nextpkt;
2399 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2400 if (m != NULL &&
pr->pr_flags & PR_ATOMIC) {
2402 if ((
flags & MSG_PEEK) == 0)
2405 if ((
flags & MSG_PEEK) == 0) {
2412 so->so_rcv.sb_mb = nextrecord;
2413 if (so->so_rcv.sb_mb == NULL) {
2414 so->so_rcv.sb_mbtail = NULL;
2415 so->so_rcv.sb_lastrecord = NULL;
2416 }
else if (nextrecord->m_nextpkt == NULL)
2417 so->so_rcv.sb_lastrecord = nextrecord;
2419 SBLASTRECORDCHK(&so->so_rcv);
2420 SBLASTMBUFCHK(&so->so_rcv);
2426 if (!(
flags & MSG_SOCALLBCK) &&
2427 (
pr->pr_flags & PR_WANTRCVD)) {
2428 SOCKBUF_UNLOCK(&so->so_rcv);
2430 (*
pr->pr_usrreqs->pru_rcvd)(so,
flags);
2431 SOCKBUF_LOCK(&so->so_rcv);
2434 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2435 if (orig_resid == uio->uio_resid && orig_resid &&
2436 (
flags & MSG_EOR) == 0 && (so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0) {
2437 SOCKBUF_UNLOCK(&so->so_rcv);
2440 SOCKBUF_UNLOCK(&so->so_rcv);
2445 SOCK_IO_RECV_UNLOCK(so);
2454 struct mbuf **mp0,
struct mbuf **controlp,
int *flagsp)
2456 int len = 0, error = 0,
flags, oresid;
2458 struct mbuf *m, *n = NULL;
2461 if (so->so_type != SOCK_STREAM)
2466 flags = *flagsp &~ MSG_EOR;
2469 if (controlp != NULL)
2471 if (
flags & MSG_OOB)
2486 if (sb->sb_tls_info != NULL)
2492 error = SOCK_IO_RECV_LOCK(so, SBLOCKWAIT(
flags));
2498 if (sb->sb_tls_info != NULL) {
2500 SOCK_IO_RECV_UNLOCK(so);
2507 if (uio->uio_resid == 0) {
2511 oresid = uio->uio_resid;
2514 if (!(so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED))) {
2520 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2524 if (sbavail(sb) > 0)
2526 if (oresid > uio->uio_resid)
2528 error = so->so_error;
2529 if (!(
flags & MSG_PEEK))
2535 if (sb->sb_state & SBS_CANTRCVMORE) {
2536 if (sbavail(sb) > 0)
2543 if (sbavail(sb) == 0 &&
2544 ((so->so_state & SS_NBIO) || (
flags & (MSG_DONTWAIT|MSG_NBIO)))) {
2550 if (sbavail(sb) > 0 && !(
flags & MSG_WAITALL) &&
2551 ((so->so_state & SS_NBIO) ||
2552 (
flags & (MSG_DONTWAIT|MSG_NBIO)) ||
2553 sbavail(sb) >= sb->sb_lowat ||
2554 sbavail(sb) >= uio->uio_resid ||
2555 sbavail(sb) >= sb->sb_hiwat) ) {
2560 if ((
flags & MSG_WAITALL) &&
2561 (sbavail(sb) >= uio->uio_resid || sbavail(sb) >= sb->sb_hiwat))
2574 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2575 KASSERT(sbavail(sb) > 0, (
"%s: sockbuf empty", __func__));
2576 KASSERT(sb->sb_mb != NULL, (
"%s: sb_mb == NULL", __func__));
2580 uio->uio_td->td_ru.ru_msgrcv++;
2583 len = min(uio->uio_resid, sbavail(sb));
2586 if (!(
flags & MSG_PEEK) && len >= sb->sb_mb->m_len) {
2590 m_cat(*mp0, sb->sb_mb);
2592 m != NULL && m->m_len <= len;
2594 KASSERT(!(m->m_flags & M_NOTAVAIL),
2595 (
"%s: m %p not available", __func__, m));
2597 uio->uio_resid -= m->m_len;
2603 sb->sb_lastrecord = sb->sb_mb;
2604 if (sb->sb_mb == NULL)
2609 KASSERT(sb->sb_mb != NULL,
2610 (
"%s: len > 0 && sb->sb_mb empty", __func__));
2612 m =
m_copym(sb->sb_mb, 0, len, M_NOWAIT);
2616 uio->uio_resid -= len;
2634 SBLASTRECORDCHK(sb);
2641 if (!(
flags & MSG_PEEK)) {
2646 if ((so->so_proto->pr_flags & PR_WANTRCVD) &&
2647 (((
flags & MSG_WAITALL) && uio->uio_resid > 0) ||
2648 !(
flags & MSG_SOCALLBCK))) {
2651 (*so->so_proto->pr_usrreqs->pru_rcvd)(so,
flags);
2660 if ((
flags & MSG_WAITALL) && uio->uio_resid > 0)
2663 SBLASTRECORDCHK(sb);
2666 SOCK_IO_RECV_UNLOCK(so);
2678 struct mbuf **mp0,
struct mbuf **controlp,
int *flagsp)
2680 struct mbuf *m, *m2;
2683 struct protosw *
pr = so->so_proto;
2684 struct mbuf *nextrecord;
2688 if (controlp != NULL)
2691 flags = *flagsp &~ MSG_EOR;
2699 if (mp0 != NULL || (
flags & MSG_PEEK) || (
flags & MSG_OOB))
2706 KASSERT((
pr->pr_flags & PR_WANTRCVD) == 0,
2707 (
"soreceive_dgram: wantrcvd"));
2708 KASSERT(
pr->pr_flags & PR_ATOMIC, (
"soreceive_dgram: !atomic"));
2709 KASSERT((so->so_rcv.sb_state & SBS_RCVATMARK) == 0,
2710 (
"soreceive_dgram: SBS_RCVATMARK"));
2711 KASSERT((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0,
2712 (
"soreceive_dgram: P_CONNREQUIRED"));
2717 SOCKBUF_LOCK(&so->so_rcv);
2718 while ((m = so->so_rcv.sb_mb) == NULL) {
2719 KASSERT(sbavail(&so->so_rcv) == 0,
2720 (
"soreceive_dgram: sb_mb NULL but sbavail %u",
2721 sbavail(&so->so_rcv)));
2723 error = so->so_error;
2725 SOCKBUF_UNLOCK(&so->so_rcv);
2728 if (so->so_rcv.sb_state & SBS_CANTRCVMORE ||
2729 uio->uio_resid == 0) {
2730 SOCKBUF_UNLOCK(&so->so_rcv);
2733 if ((so->so_state & SS_NBIO) ||
2734 (
flags & (MSG_DONTWAIT|MSG_NBIO))) {
2735 SOCKBUF_UNLOCK(&so->so_rcv);
2736 return (EWOULDBLOCK);
2738 SBLASTRECORDCHK(&so->so_rcv);
2739 SBLASTMBUFCHK(&so->so_rcv);
2740 error =
sbwait(&so->so_rcv);
2742 SOCKBUF_UNLOCK(&so->so_rcv);
2746 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
2749 uio->uio_td->td_ru.ru_msgrcv++;
2750 SBLASTRECORDCHK(&so->so_rcv);
2751 SBLASTMBUFCHK(&so->so_rcv);
2752 nextrecord = m->m_nextpkt;
2753 if (nextrecord == NULL) {
2754 KASSERT(so->so_rcv.sb_lastrecord == m,
2755 (
"soreceive_dgram: lastrecord != m"));
2758 KASSERT(so->so_rcv.sb_mb->m_nextpkt == nextrecord,
2759 (
"soreceive_dgram: m_nextpkt != nextrecord"));
2764 so->so_rcv.sb_mb = NULL;
2770 for (m2 = m; m2 != NULL; m2 = m2->m_next)
2776 SBLASTRECORDCHK(&so->so_rcv);
2777 SBLASTMBUFCHK(&so->so_rcv);
2778 SOCKBUF_UNLOCK(&so->so_rcv);
2780 if (
pr->pr_flags & PR_ADDR) {
2781 KASSERT(m->m_type == MT_SONAME,
2782 (
"m->m_type == %d", m->m_type));
2803 if (m->m_type == MT_CONTROL) {
2804 struct mbuf *cm = NULL, *cmn;
2805 struct mbuf **cme = &cm;
2811 cme = &(*cme)->m_next;
2813 }
while (m != NULL && m->m_type == MT_CONTROL);
2814 while (cm != NULL) {
2817 if (
pr->pr_domain->dom_externalize != NULL) {
2818 error = (*
pr->pr_domain->dom_externalize)
2819 (cm, controlp,
flags);
2820 }
else if (controlp != NULL)
2824 if (controlp != NULL) {
2825 while (*controlp != NULL)
2826 controlp = &(*controlp)->m_next;
2831 KASSERT(m == NULL || m->m_type == MT_DATA,
2832 (
"soreceive_dgram: !data"));
2833 while (m != NULL && uio->uio_resid > 0) {
2834 len = uio->uio_resid;
2837 error =
uiomove(mtod(m,
char *), (
int)len, uio);
2842 if (len == m->m_len)
2859soreceive(
struct socket *so,
struct sockaddr **psa,
struct uio *uio,
2860 struct mbuf **mp0,
struct mbuf **controlp,
int *flagsp)
2864 CURVNET_SET(so->so_vnet);
2865 error = (so->so_proto->pr_usrreqs->pru_soreceive(so, psa, uio,
2866 mp0, controlp, flagsp));
2875 int error, soerror_enotconn;
2877 if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))
2880 soerror_enotconn = 0;
2883 (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) {
2893 if (so->so_type != SOCK_DGRAM && !SOLISTENING(so)) {
2897 soerror_enotconn = 1;
2900 if (SOLISTENING(so)) {
2901 if (how != SHUT_WR) {
2902 so->so_error = ECONNABORTED;
2911 CURVNET_SET(so->so_vnet);
2913 if (
pr->pr_usrreqs->pru_flush != NULL)
2914 (*
pr->pr_usrreqs->pru_flush)(so, how);
2917 if (how != SHUT_RD) {
2918 error = (*
pr->pr_usrreqs->pru_shutdown)(so);
2921 return ((error == 0 && soerror_enotconn) ? ENOTCONN : error);
2927 return (soerror_enotconn ? ENOTCONN : 0);
2956 error = SOCK_IO_RECV_LOCK(so, SBL_WAIT | SBL_NOINTR);
2958 KASSERT(SOLISTENING(so),
2959 (
"%s: soiolock(%p) failed", __func__, so));
2963 SOCK_RECVBUF_LOCK(so);
2964 bzero(&aso,
sizeof(aso));
2965 aso.so_pcb = so->so_pcb;
2966 bcopy(&so->so_rcv.sb_startzero, &aso.so_rcv.sb_startzero,
2967 offsetof(
struct sockbuf, sb_endzero) -
2968 offsetof(
struct sockbuf, sb_startzero));
2969 bzero(&so->so_rcv.sb_startzero,
2970 offsetof(
struct sockbuf, sb_endzero) -
2971 offsetof(
struct sockbuf, sb_startzero));
2972 SOCK_RECVBUF_UNLOCK(so);
2973 SOCK_IO_RECV_UNLOCK(so);
2980 if (
pr->pr_flags & PR_RIGHTS &&
pr->pr_domain->dom_dispose != NULL)
2981 (*
pr->pr_domain->dom_dispose)(&aso);
2992 struct socket_hhook_data hhook_data = {
2999 CURVNET_SET(so->so_vnet);
3000 HHOOKS_RUN_IF(
V_socket_hhh[h_id], &hhook_data, &so->osd);
3004 return (hhook_data.status);
3025 if ((valsize = sopt->sopt_valsize) < minlen)
3028 sopt->sopt_valsize = valsize = len;
3030 if (sopt->sopt_td != NULL)
3031 return (copyin(sopt->sopt_val,
buf, valsize));
3033 bcopy(sopt->sopt_val,
buf, valsize);
3046 struct sockopt sopt;
3048 sopt.sopt_level =
level;
3049 sopt.sopt_name = optname;
3050 sopt.sopt_dir = SOPT_SET;
3051 sopt.sopt_val = optval;
3052 sopt.sopt_valsize = optlen;
3053 sopt.sopt_td = NULL;
3069 CURVNET_SET(so->so_vnet);
3071 if (sopt->sopt_level != SOL_SOCKET) {
3072 if (so->so_proto->pr_ctloutput != NULL)
3073 error = (*so->so_proto->pr_ctloutput)(so, sopt);
3075 error = ENOPROTOOPT;
3077 switch (sopt->sopt_name) {
3078 case SO_ACCEPTFILTER:
3085 error =
sooptcopyin(sopt, &l,
sizeof l,
sizeof l);
3088 if (l.l_linger < 0 ||
3089 l.l_linger > USHRT_MAX ||
3090 l.l_linger > (INT_MAX /
hz)) {
3095 so->so_linger = l.l_linger;
3097 so->so_options |= SO_LINGER;
3099 so->so_options &= ~SO_LINGER;
3106 case SO_USELOOPBACK:
3110 case SO_REUSEPORT_LB:
3124 so->so_options |= sopt->sopt_name;
3126 so->so_options &= ~sopt->sopt_name;
3136 if (optval < 0 || optval >= rt_numfibs) {
3140 if (((so->so_proto->pr_domain->dom_family == PF_INET) ||
3141 (so->so_proto->pr_domain->dom_family == PF_INET6) ||
3142 (so->so_proto->pr_domain->dom_family == PF_ROUTE)))
3143 so->so_fibnum = optval;
3148 case SO_USER_COOKIE:
3153 so->so_user_cookie = val32;
3174 error =
sbsetopt(so, sopt->sopt_name, optval);
3179#ifdef COMPAT_FREEBSD32
3180 if (SV_CURPROC_FLAG(SV_ILP32)) {
3181 struct timeval32 tv32;
3185 CP(tv32, tv, tv_sec);
3186 CP(tv32, tv, tv_usec);
3193 if (tv.tv_sec < 0 || tv.tv_usec < 0 ||
3194 tv.tv_usec >= 1000000) {
3198 if (tv.tv_sec > INT32_MAX)
3202 switch (sopt->sopt_name) {
3204 so->so_snd.sb_timeo = val;
3207 so->so_rcv.sb_timeo = val;
3218 error = mac_setsockopt_label(sopt->sopt_td->td_ucred,
3230 if (optval < 0 || optval > SO_TS_CLOCK_MAX) {
3234 so->so_ts_clock = optval;
3237 case SO_MAX_PACING_RATE:
3242 so->so_max_pacing_rate = val32;
3250 error = ENOPROTOOPT;
3253 if (error == 0 && so->so_proto->pr_ctloutput != NULL)
3254 (void)(*so->so_proto->pr_ctloutput)(so, sopt);
3280 valsize = min(len, sopt->sopt_valsize);
3281 sopt->sopt_valsize = valsize;
3282 if (sopt->sopt_val != NULL) {
3283 if (sopt->sopt_td != NULL)
3284 error = copyout(
buf, sopt->sopt_val, valsize);
3286 bcopy(
buf, sopt->sopt_val, valsize);
3301 CURVNET_SET(so->so_vnet);
3303 if (sopt->sopt_level != SOL_SOCKET) {
3304 if (so->so_proto->pr_ctloutput != NULL)
3305 error = (*so->so_proto->pr_ctloutput)(so, sopt);
3307 error = ENOPROTOOPT;
3311 switch (sopt->sopt_name) {
3312 case SO_ACCEPTFILTER:
3318 l.l_onoff = so->so_options & SO_LINGER;
3319 l.l_linger = so->so_linger;
3324 case SO_USELOOPBACK:
3330 case SO_REUSEPORT_LB:
3340 optval = so->so_options & sopt->sopt_name;
3346 optval = so->so_proto->pr_domain->dom_family;
3350 optval = so->so_type;
3354 optval = so->so_proto->pr_protocol;
3360 optval = so->so_error;
3363 optval = so->so_rerror;
3370 optval = SOLISTENING(so) ? so->sol_sbsnd_hiwat :
3371 so->so_snd.sb_hiwat;
3375 optval = SOLISTENING(so) ? so->sol_sbrcv_hiwat :
3376 so->so_rcv.sb_hiwat;
3380 optval = SOLISTENING(so) ? so->sol_sbsnd_lowat :
3381 so->so_snd.sb_lowat;
3385 optval = SOLISTENING(so) ? so->sol_sbrcv_lowat :
3386 so->so_rcv.sb_lowat;
3391 tv = sbttotv(sopt->sopt_name == SO_SNDTIMEO ?
3392 so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
3393#ifdef COMPAT_FREEBSD32
3394 if (SV_CURPROC_FLAG(SV_ILP32)) {
3395 struct timeval32 tv32;
3397 CP(tv, tv32, tv_sec);
3398 CP(tv, tv32, tv_usec);
3407 error =
sooptcopyin(sopt, &extmac,
sizeof(extmac),
3411 error = mac_getsockopt_label(sopt->sopt_td->td_ucred,
3423 error =
sooptcopyin(sopt, &extmac,
sizeof(extmac),
3427 error = mac_getsockopt_peerlabel(
3428 sopt->sopt_td->td_ucred, so, &extmac);
3437 case SO_LISTENQLIMIT:
3438 optval = SOLISTENING(so) ? so->sol_qlimit : 0;
3442 optval = SOLISTENING(so) ? so->sol_qlen : 0;
3445 case SO_LISTENINCQLEN:
3446 optval = SOLISTENING(so) ? so->sol_incqlen : 0;
3450 optval = so->so_ts_clock;
3453 case SO_MAX_PACING_RATE:
3454 optval = so->so_max_pacing_rate;
3462 error = ENOPROTOOPT;
3476 struct mbuf *m, *m_prev;
3477 int sopt_size = sopt->sopt_valsize;
3479 MGET(m, sopt->sopt_td ? M_WAITOK : M_NOWAIT, MT_DATA);
3482 if (sopt_size > MLEN) {
3483 MCLGET(m, sopt->sopt_td ? M_WAITOK : M_NOWAIT);
3484 if ((m->m_flags & M_EXT) == 0) {
3488 m->m_len = min(MCLBYTES, sopt_size);
3490 m->m_len = min(MLEN, sopt_size);
3492 sopt_size -= m->m_len;
3497 MGET(m, sopt->sopt_td ? M_WAITOK : M_NOWAIT, MT_DATA);
3502 if (sopt_size > MLEN) {
3503 MCLGET(m, sopt->sopt_td != NULL ? M_WAITOK :
3505 if ((m->m_flags & M_EXT) == 0) {
3510 m->m_len = min(MCLBYTES, sopt_size);
3512 m->m_len = min(MLEN, sopt_size);
3514 sopt_size -= m->m_len;
3524 struct mbuf *m0 = m;
3526 if (sopt->sopt_val == NULL)
3528 while (m != NULL && sopt->sopt_valsize >= m->m_len) {
3529 if (sopt->sopt_td != NULL) {
3532 error = copyin(sopt->sopt_val, mtod(m,
char *),
3539 bcopy(sopt->sopt_val, mtod(m,
char *), m->m_len);
3540 sopt->sopt_valsize -= m->m_len;
3541 sopt->sopt_val = (
char *)sopt->sopt_val + m->m_len;
3545 panic(
"ip6_sooptmcopyin");
3552 struct mbuf *m0 = m;
3555 if (sopt->sopt_val == NULL)
3557 while (m != NULL && sopt->sopt_valsize >= m->m_len) {
3558 if (sopt->sopt_td != NULL) {
3561 error = copyout(mtod(m,
char *), sopt->sopt_val,
3568 bcopy(mtod(m,
char *), sopt->sopt_val, m->m_len);
3569 sopt->sopt_valsize -= m->m_len;
3570 sopt->sopt_val = (
char *)sopt->sopt_val + m->m_len;
3571 valsize += m->m_len;
3579 sopt->sopt_valsize = valsize;
3591 if (so->so_sigio != NULL)
3592 pgsigio(&so->so_sigio, SIGURG, 0);
3597sopoll(
struct socket *so,
int events,
struct ucred *active_cred,
3605 return (so->so_proto->pr_usrreqs->pru_sopoll(so, events, active_cred,
3616 if (SOLISTENING(so)) {
3617 if (!(events & (POLLIN | POLLRDNORM)))
3619 else if (!TAILQ_EMPTY(&so->sol_comp))
3620 revents = events & (POLLIN | POLLRDNORM);
3621 else if ((events & POLLINIGNEOF) == 0 && so->so_error)
3622 revents = (events & (POLLIN | POLLRDNORM)) | POLLHUP;
3629 SOCKBUF_LOCK(&so->so_snd);
3630 SOCKBUF_LOCK(&so->so_rcv);
3631 if (events & (POLLIN | POLLRDNORM))
3632 if (soreadabledata(so))
3633 revents |= events & (POLLIN | POLLRDNORM);
3634 if (events & (POLLOUT | POLLWRNORM))
3635 if (sowriteable(so))
3636 revents |= events & (POLLOUT | POLLWRNORM);
3637 if (events & (POLLPRI | POLLRDBAND))
3638 if (so->so_oobmark ||
3639 (so->so_rcv.sb_state & SBS_RCVATMARK))
3640 revents |= events & (POLLPRI | POLLRDBAND);
3641 if ((events & POLLINIGNEOF) == 0) {
3642 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
3643 revents |= events & (POLLIN | POLLRDNORM);
3644 if (so->so_snd.sb_state & SBS_CANTSENDMORE)
3648 if (so->so_rcv.sb_state & SBS_CANTRCVMORE)
3649 revents |= events & POLLRDHUP;
3652 (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND | POLLRDHUP)) {
3654 so->so_rcv.sb_flags |= SB_SEL;
3656 if (events & (POLLOUT | POLLWRNORM)) {
3658 so->so_snd.sb_flags |= SB_SEL;
3661 SOCKBUF_UNLOCK(&so->so_rcv);
3662 SOCKBUF_UNLOCK(&so->so_snd);
3671 struct socket *so = kn->kn_fp->f_data;
3675 switch (kn->kn_filter) {
3678 knl = &so->so_rdsel.si_note;
3683 knl = &so->so_wrsel.si_note;
3688 knl = &so->so_wrsel.si_note;
3696 if (SOLISTENING(so)) {
3701 sb->sb_flags |= SB_KNOTE;
3772 struct ifnet *ifp,
struct thread *td)
3815 struct sockaddr *
addr,
struct mbuf *control,
struct thread *td)
3818 if (control != NULL)
3820 if ((
flags & PRUS_NOTREADY) == 0)
3822 return (EOPNOTSUPP);
3829 return (EOPNOTSUPP);
3840 sb->st_blksize = so->so_snd.sb_hiwat;
3860 struct mbuf *top,
struct mbuf *control,
int flags,
struct thread *td)
3868 struct uio *uio,
struct mbuf **mp0,
struct mbuf **controlp,
int *flagsp)
3885 struct socket *so = kn->kn_fp->f_data;
3889 if (!SOLISTENING(so) &&
knlist_empty(&so->so_rdsel.si_note))
3890 so->so_rcv.sb_flags &= ~SB_KNOTE;
3900 so = kn->kn_fp->f_data;
3902 if (SOLISTENING(so)) {
3903 SOCK_LOCK_ASSERT(so);
3904 kn->kn_data = so->sol_qlen;
3906 kn->kn_flags |= EV_EOF;
3907 kn->kn_fflags = so->so_error;
3910 return (!TAILQ_EMPTY(&so->sol_comp));
3913 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
3915 kn->kn_data = sbavail(&so->so_rcv) - so->so_rcv.sb_ctl;
3916 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
3917 kn->kn_flags |= EV_EOF;
3918 kn->kn_fflags = so->so_error;
3920 }
else if (so->so_error || so->so_rerror)
3923 if (kn->kn_sfflags & NOTE_LOWAT) {
3924 if (kn->kn_data >= kn->kn_sdata)
3926 }
else if (sbavail(&so->so_rcv) >= so->so_rcv.sb_lowat)
3936 struct socket *so = kn->kn_fp->f_data;
3940 if (!SOLISTENING(so) &&
knlist_empty(&so->so_wrsel.si_note))
3941 so->so_snd.sb_flags &= ~SB_KNOTE;
3951 so = kn->kn_fp->f_data;
3953 if (SOLISTENING(so))
3956 SOCKBUF_LOCK_ASSERT(&so->so_snd);
3957 kn->kn_data = sbspace(&so->so_snd);
3961 if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
3962 kn->kn_flags |= EV_EOF;
3963 kn->kn_fflags = so->so_error;
3965 }
else if (so->so_error)
3967 else if (((so->so_state & SS_ISCONNECTED) == 0) &&
3968 (so->so_proto->pr_flags & PR_CONNREQUIRED))
3970 else if (kn->kn_sfflags & NOTE_LOWAT)
3971 return (kn->kn_data >= kn->kn_sdata);
3973 return (kn->kn_data >= so->so_snd.sb_lowat);
3981 so = kn->kn_fp->f_data;
3983 if (SOLISTENING(so))
3986 SOCKBUF_LOCK_ASSERT(&so->so_snd);
3987 kn->kn_data = sbused(&so->so_snd);
3989 if (kn->kn_data == 0)
4001 if (so->so_cred->cr_uid != uid)
4043 so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
4044 so->so_state |= SS_ISCONNECTING;
4051 bool last __diagused;
4054 so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
4055 so->so_state |= SS_ISCONNECTED;
4057 if (so->so_qstate == SQ_INCOMP) {
4058 struct socket *head = so->so_listen;
4061 KASSERT(head, (
"%s: so %p on incomp of NULL", __func__, so));
4069 if (__predict_false(SOLISTEN_TRYLOCK(head) == 0)) {
4072 SOLISTEN_LOCK(head);
4074 if (__predict_false(head != so->so_listen)) {
4084 last = refcount_release(&head->so_count);
4085 KASSERT(!last, (
"%s: released last reference for %p",
4089 if ((so->so_options & SO_ACCEPTFILTER) == 0) {
4090 TAILQ_REMOVE(&head->sol_incomp, so, so_list);
4091 head->sol_incqlen--;
4092 TAILQ_INSERT_TAIL(&head->sol_comp, so, so_list);
4094 so->so_qstate = SQ_COMP;
4098 SOCKBUF_LOCK(&so->so_rcv);
4100 head->sol_accept_filter->accf_callback,
4101 head->sol_accept_filter_arg);
4102 so->so_options &= ~SO_ACCEPTFILTER;
4103 ret = head->sol_accept_filter->accf_callback(so,
4104 head->sol_accept_filter_arg, M_NOWAIT);
4105 if (ret == SU_ISCONNECTED) {
4107 SOCKBUF_UNLOCK(&so->so_rcv);
4110 SOCKBUF_UNLOCK(&so->so_rcv);
4112 SOLISTEN_UNLOCK(head);
4127 so->so_state &= ~SS_ISCONNECTING;
4128 so->so_state |= SS_ISDISCONNECTING;
4130 if (!SOLISTENING(so)) {
4131 SOCKBUF_LOCK(&so->so_rcv);
4133 SOCKBUF_LOCK(&so->so_snd);
4153 so->so_state |= SS_ISDISCONNECTED;
4154 atomic_thread_fence_rel();
4155 so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
4157 if (!SOLISTENING(so)) {
4159 SOCKBUF_LOCK(&so->so_rcv);
4161 SOCKBUF_LOCK(&so->so_snd);
4175 (
"soiolock: invalid flags %#x",
flags));
4177 if ((
flags & SBL_WAIT) != 0) {
4178 if ((
flags & SBL_NOINTR) != 0) {
4181 error = sx_xlock_sig(sx);
4185 }
else if (!sx_try_xlock(sx)) {
4186 return (EWOULDBLOCK);
4189 if (__predict_false(SOLISTENING(so))) {
4208 struct sockaddr *sa2;
4210 sa2 =
malloc(sa->sa_len, M_SONAME, mflags);
4212 bcopy(sa, sa2, sa->sa_len);
4223 SOCK_LOCK_ASSERT(so);
4235 KASSERT(!SOLISTENING(so), (
"%s: so %p listening", __func__, so));
4245 panic(
"soupcall_set: bad which");
4247 SOCKBUF_LOCK_ASSERT(sb);
4248 sb->sb_upcall = func;
4249 sb->sb_upcallarg = arg;
4250 sb->sb_flags |= SB_UPCALL;
4258 KASSERT(!SOLISTENING(so), (
"%s: so %p listening", __func__, so));
4268 panic(
"soupcall_clear: bad which");
4270 SOCKBUF_LOCK_ASSERT(sb);
4271 KASSERT(sb->sb_upcall != NULL,
4272 (
"%s: so %p no upcall to clear", __func__, so));
4273 sb->sb_upcall = NULL;
4274 sb->sb_upcallarg = NULL;
4275 sb->sb_flags &= ~SB_UPCALL;
4282 SOLISTEN_LOCK_ASSERT(so);
4283 so->sol_upcall = func;
4284 so->sol_upcallarg = arg;
4290 struct socket *so = arg;
4292 if (SOLISTENING(so))
4295 SOCKBUF_LOCK(&so->so_rcv);
4301 struct socket *so = arg;
4303 if (SOLISTENING(so))
4306 SOCKBUF_UNLOCK(&so->so_rcv);
4312 struct socket *so = arg;
4314 if (what == LA_LOCKED) {
4315 if (SOLISTENING(so))
4316 SOCK_LOCK_ASSERT(so);
4318 SOCKBUF_LOCK_ASSERT(&so->so_rcv);
4320 if (SOLISTENING(so))
4321 SOCK_UNLOCK_ASSERT(so);
4323 SOCKBUF_UNLOCK_ASSERT(&so->so_rcv);
4330 struct socket *so = arg;
4332 if (SOLISTENING(so))
4335 SOCKBUF_LOCK(&so->so_snd);
4341 struct socket *so = arg;
4343 if (SOLISTENING(so))
4346 SOCKBUF_UNLOCK(&so->so_snd);
4352 struct socket *so = arg;
4354 if (what == LA_LOCKED) {
4355 if (SOLISTENING(so))
4356 SOCK_LOCK_ASSERT(so);
4358 SOCKBUF_LOCK_ASSERT(&so->so_snd);
4360 if (SOLISTENING(so))
4361 SOCK_UNLOCK_ASSERT(so);
4363 SOCKBUF_UNLOCK_ASSERT(&so->so_snd);
4379 bzero(xso,
sizeof(*xso));
4380 xso->xso_len =
sizeof *xso;
4381 xso->xso_so = (uintptr_t)so;
4382 xso->so_type = so->so_type;
4383 xso->so_options = so->so_options;
4384 xso->so_linger = so->so_linger;
4385 xso->so_state = so->so_state;
4386 xso->so_pcb = (uintptr_t)so->so_pcb;
4387 xso->xso_protocol = so->so_proto->pr_protocol;
4388 xso->xso_family = so->so_proto->pr_domain->dom_family;
4389 xso->so_timeo = so->so_timeo;
4390 xso->so_error = so->so_error;
4391 xso->so_uid = so->so_cred->cr_uid;
4392 xso->so_pgid = so->so_sigio ? so->so_sigio->sio_pgid : 0;
4393 if (SOLISTENING(so)) {
4394 xso->so_qlen = so->sol_qlen;
4395 xso->so_incqlen = so->sol_incqlen;
4396 xso->so_qlimit = so->sol_qlimit;
4397 xso->so_oobmark = 0;
4399 xso->so_state |= so->so_qstate;
4400 xso->so_qlen = xso->so_incqlen = xso->so_qlimit = 0;
4401 xso->so_oobmark = so->so_oobmark;
4411 return (&so->so_rcv);
4418 return (&so->so_snd);
4425 return (so->so_state);
4439 return (so->so_options);
4446 so->so_options = val;
4453 return (so->so_error);
4467 return (so->so_linger);
4474 KASSERT(val >= 0 && val <= USHRT_MAX && val <= (INT_MAX /
hz),
4475 (
"%s: val %d out of range", __func__, val));
4477 so->so_linger = val;
4484 return (so->so_proto);
4512 sorwakeup_locked(so);
4519 sowwakeup_locked(so);
const struct cf_level * level
device_property_type_t type
void funsetown(struct sigio **sigiop)
void knlist_remove(struct knlist *knl, struct knote *kn, int islocked)
void knlist_init(struct knlist *knl, void *lock, void(*kl_lock)(void *), void(*kl_unlock)(void *), void(*kl_assert_lock)(void *, int))
void knlist_add(struct knlist *knl, struct knote *kn, int islocked)
void knlist_destroy(struct knlist *knl)
void knote(struct knlist *list, long hint, int lockflags)
int knlist_empty(struct knlist *knl)
int hhook_head_deregister(struct hhook_head *hhh)
int hhook_head_register(int32_t hhook_type, int32_t hhook_id, struct hhook_head **hhh, uint32_t flags)
int prison_check_af(struct ucred *cred, int af)
int khelp_init_osd(uint32_t classes, struct osd *hosd)
int khelp_destroy_osd(struct osd *hosd)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void m_freem(struct mbuf *mb)
static struct pollrec pr[POLL_LIST_LEN]
struct ucred * crhold(struct ucred *cr)
void crfree(struct ucred *cr)
int chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to, rlim_t max)
void panic(const char *fmt,...)
void pgsigio(struct sigio **sigiop, int sig, int checkctty)
void sx_destroy(struct sx *sx)
void wakeup(const void *ident)
void wakeup_one(const void *ident)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
int ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
int printf(const char *fmt,...)
void log(int level, const char *fmt,...)
int sbuf_finish(struct sbuf *s)
void sbuf_delete(struct sbuf *s)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
int sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
ssize_t sbuf_len(struct sbuf *s)
char * sbuf_data(struct sbuf *s)
void sbuf_clear(struct sbuf *s)
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
int sbuf_cat(struct sbuf *s, const char *str)
int uiomove(void *cp, int n, struct uio *uio)
void selwakeuppri(struct selinfo *sip, int pri)
void seldrain(struct selinfo *sip)
void selrecord(struct thread *selector, struct selinfo *sip)
void soaio_snd(void *context, int pending)
void soaio_rcv(void *context, int pending)
int accept_filt_getopt(struct socket *so, struct sockopt *sopt)
int accept_filt_setopt(struct socket *so, struct sockopt *sopt)
struct protosw * pffindproto(int family, int protocol, int type)
struct domain * pffinddomain(int family)
struct protosw * pffindtype(int family, int type)
bool ktls_permit_empty_frames(struct ktls_session *tls)
void ktls_enqueue(struct mbuf *m, struct socket *so, int page_count)
void ktls_frame(struct mbuf *top, struct ktls_session *tls, int *enq_cnt, uint8_t record_type)
u_int m_length(struct mbuf *m0, struct mbuf **last)
int m_unmapped_uiomove(const struct mbuf *m, int m_off, struct uio *uio, int len)
void m_cat(struct mbuf *m, struct mbuf *n)
struct mbuf * m_copym(struct mbuf *m, int off0, int len, int wait)
int m_mbuftouio(struct uio *uio, const struct mbuf *m, int len)
struct mbuf * m_uiotombuf(struct uio *uio, int how, int len, int align, int flags)
int sbwait(struct sockbuf *sb)
void socantsendmore_locked(struct socket *so)
int sbsetopt(struct socket *so, int cmd, u_long cc)
void sbfree(struct sockbuf *sb, struct mbuf *m)
int soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
void sbdestroy(struct sockbuf *sb, struct socket *so)
void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb)
void socantrcvmore_locked(struct socket *so)
void sbdroprecord_locked(struct sockbuf *sb)
struct mbuf * sbcut_locked(struct sockbuf *sb, int len)
void sbdrop_locked(struct sockbuf *sb, int len)
void sbrelease_internal(struct sockbuf *sb, struct socket *so)
void socantrcvmore(struct socket *so)
int sosetopt(struct socket *so, struct sockopt *sopt)
void so_protosw_set(struct socket *so, struct protosw *val)
int pru_bind_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
int sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
int pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags)
static void so_wrknl_lock(void *)
static struct filterops sowrite_filtops
int pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred, struct thread *td)
void sofree(struct socket *so)
void solisten_upcall_set(struct socket *so, so_upcall_t func, void *arg)
int solisten(struct socket *so, int backlog, struct thread *td)
static struct socket * soalloc(struct vnet *vnet)
int solisten_dequeue(struct socket *head, struct socket **ret, int flags)
static struct timeval overinterval
int pru_listen_notsupp(struct socket *so, int backlog, struct thread *td)
int soopt_getm(struct sockopt *sopt, struct mbuf **mp)
int sobind(struct socket *so, struct sockaddr *nam, struct thread *td)
fo_kqfilter_t soo_kqfilter
static int soreceive_rcvoob(struct socket *so, struct uio *uio, int flags)
#define VNET_SO_ASSERT(so)
static void so_wrknl_assert_lock(void *, int)
static int numopensockets
int pru_peeraddr_notsupp(struct socket *so, struct sockaddr **nam)
void so_sowwakeup_locked(struct socket *so)
VNET_SYSINIT(socket_vnet_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, socket_vnet_init, NULL)
static int filt_soread(struct knote *kn, long hint)
int solisten_proto_check(struct socket *so)
int pru_shutdown_notsupp(struct socket *so)
void sorflush(struct socket *so)
struct socket * sonewconn(struct socket *head, int connstatus)
int soreceive_stream(struct socket *so, struct sockaddr **psa, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
static int hhook_run_socket(struct socket *so, void *hctx, int32_t h_id)
struct protosw * so_protosw_get(const struct socket *so)
struct sockbuf * so_sockbuf_snd(struct socket *so)
int sodisconnect(struct socket *so)
MALLOC_DEFINE(M_SONAME, "soname", "socket name")
int pru_attach_notsupp(struct socket *so, int proto, struct thread *td)
int pru_aio_queue_notsupp(struct socket *so, struct kaiocb *job)
static int sysctl_somaxconn(SYSCTL_HANDLER_ARGS)
void so_linger_set(struct socket *so, int val)
static void so_wrknl_unlock(void *)
void soisdisconnected(struct socket *so)
void so_state_set(struct socket *so, int val)
int soopt_mcopyout(struct sockopt *sopt, struct mbuf *m)
static void so_rdknl_assert_lock(void *, int)
static int filt_soempty(struct knote *kn, long hint)
void solisten_proto_abort(struct socket *so)
static struct mtx so_global_mtx
int pru_rcvd_notsupp(struct socket *so, int flags)
int pru_accept_notsupp(struct socket *so, struct sockaddr **nam)
static int sysctl_maxsockets(SYSCTL_HANDLER_ARGS)
static struct filterops soread_filtops
void solisten_wakeup(struct socket *sol)
int soconnect2(struct socket *so1, struct socket *so2)
int socreate(int dom, struct socket **aso, int type, int proto, struct ucred *cred, struct thread *td)
int pru_sense_null(struct socket *so, struct stat *sb)
void so_sorwakeup_locked(struct socket *so)
int so_options_get(const struct socket *so)
int pru_sosend_notsupp(struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
int so_setsockopt(struct socket *so, int level, int optname, void *optval, size_t optlen)
static __inline void sockbuf_pushsync(struct sockbuf *sb, struct mbuf *nextrecord)
int so_linger_get(const struct socket *so)
int pru_connect2_notsupp(struct socket *so1, struct socket *so2)
int pru_ready_notsupp(struct socket *so, struct mbuf *m, int count)
int soclose(struct socket *so)
int sogetopt(struct socket *so, struct sockopt *sopt)
int pru_sockaddr_notsupp(struct socket *so, struct sockaddr **nam)
int sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
VNET_DEFINE(struct hhook_head *, socket_hhh[HHOOK_SOCKET_LAST+1])
static void so_rdknl_lock(void *)
void so_unlock(struct socket *so)
int so_error_get(const struct socket *so)
SYSCTL_NODE(_kern, KERN_IPC, ipc, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "IPC")
int sobindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
void soisconnected(struct socket *so)
int pru_disconnect_notsupp(struct socket *so)
void soabort(struct socket *so)
int soconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
int pru_send_notsupp(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, struct mbuf *control, struct thread *td)
int soconnectat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
int pru_soreceive_notsupp(struct socket *so, struct sockaddr **paddr, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
MTX_SYSINIT(accept_mtx, &accept_mtx, "accept", MTX_DEF)
void so_error_set(struct socket *so, int val)
int so_state_get(const struct socket *so)
static uma_zone_t socket_zone
int pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
void so_lock(struct socket *so)
void sotoxsocket(struct socket *so, struct xsocket *xso)
int sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
SYSCTL_INT(_kern_ipc, OID_AUTO, numopensockets, CTLFLAG_RD, &numopensockets, 0, "Number of open sockets")
void sodtor_set(struct socket *so, so_dtor_t *func)
int socheckuid(struct socket *so, uid_t uid)
int sopoll_generic(struct socket *so, int events, struct ucred *active_cred, struct thread *td)
int pru_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
int soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
SYSCTL_TIMEVAL_SEC(_kern_ipc, OID_AUTO, sooverinterval, CTLFLAG_RW, &overinterval, "Delay in seconds between warnings for listen socket overflows")
static void filt_sowdetach(struct knote *kn)
static struct filterops soempty_filtops
void sohasoutofband(struct socket *so)
static void socket_init(void *tag)
static void so_rdknl_unlock(void *)
static void filt_sordetach(struct knote *kn)
void so_options_set(struct socket *so, int val)
void soisdisconnecting(struct socket *so)
static void socket_vnet_uninit(const void *unused __unused)
void so_sowwakeup(struct socket *so)
void sorele_locked(struct socket *so)
void soisconnecting(struct socket *so)
int soshutdown(struct socket *so, int how)
SYSINIT(socket, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, socket_init, NULL)
int soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
struct sockaddr * sodupsockaddr(const struct sockaddr *sa, int mflags)
void so_sorwakeup(struct socket *so)
static int filt_sowrite(struct knote *kn, long hint)
static void socket_hhook_register(int subtype)
static void socket_hhook_deregister(int subtype)
SYSCTL_PROC(_kern_ipc, OID_AUTO, soacceptqueue, CTLTYPE_UINT|CTLFLAG_RW|CTLFLAG_MPSAFE, 0, sizeof(int), sysctl_somaxconn, "I", "Maximum listen socket pending connection accept queue size")
void soupcall_set(struct socket *so, int which, so_upcall_t func, void *arg)
void solisten_proto(struct socket *so, int backlog)
int pru_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
static void socket_zone_change(void *tag)
int pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td)
int soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
int sopoll(struct socket *so, int events, struct ucred *active_cred, struct thread *td)
static void init_maxsockets(void *ignored)
int sooptcopyout(struct sockopt *sopt, const void *buf, size_t len)
int soopt_mcopyin(struct sockopt *sopt, struct mbuf *m)
static void sodealloc(struct socket *so)
static void socket_vnet_init(const void *unused __unused)
int soaccept(struct socket *so, struct sockaddr **nam)
void soupcall_clear(struct socket *so, int which)
int soiolock(struct socket *so, struct sx *sx, int flags)
struct sockbuf * so_sockbuf_rcv(struct socket *so)
int sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
VNET_SYSUNINIT(socket_vnet_uninit, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, socket_vnet_uninit, NULL)
void soiounlock(struct sx *sx)