Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/uipc_socket.c
Show First 20 Lines • Show All 1,458 Lines • ▼ Show 20 Lines | sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio, | ||||
if (resid < 0) { | if (resid < 0) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
dontroute = | dontroute = | ||||
(flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0; | (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0; | ||||
if (td != NULL) | if (td != NULL) | ||||
td->td_ru.ru_msgsnd++; | RU_ATOMIC_INC(td->td_ru.ru_msgsnd); | ||||
if (control != NULL) | if (control != NULL) | ||||
clen = control->m_len; | clen = control->m_len; | ||||
SOCKBUF_LOCK(&so->so_snd); | SOCKBUF_LOCK(&so->so_snd); | ||||
if (so->so_snd.sb_state & SBS_CANTSENDMORE) { | if (so->so_snd.sb_state & SBS_CANTSENDMORE) { | ||||
SOCKBUF_UNLOCK(&so->so_snd); | SOCKBUF_UNLOCK(&so->so_snd); | ||||
error = EPIPE; | error = EPIPE; | ||||
goto out; | goto out; | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | if (resid < 0 || (so->so_type == SOCK_STREAM && (flags & MSG_EOR))) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
dontroute = | dontroute = | ||||
(flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 && | (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 && | ||||
(so->so_proto->pr_flags & PR_ATOMIC); | (so->so_proto->pr_flags & PR_ATOMIC); | ||||
if (td != NULL) | if (td != NULL) | ||||
td->td_ru.ru_msgsnd++; | RU_ATOMIC_INC(td->td_ru.ru_msgsnd); | ||||
if (control != NULL) | if (control != NULL) | ||||
clen = control->m_len; | clen = control->m_len; | ||||
error = SOCK_IO_SEND_LOCK(so, SBLOCKWAIT(flags)); | error = SOCK_IO_SEND_LOCK(so, SBLOCKWAIT(flags)); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
#ifdef KERN_TLS | #ifdef KERN_TLS | ||||
▲ Show 20 Lines • Show All 424 Lines • ▼ Show 20 Lines | dontblock: | ||||
* versions of the field, possibly resulting in socket buffer | * versions of the field, possibly resulting in socket buffer | ||||
* corruption. | * corruption. | ||||
* | * | ||||
* By holding the high-level sblock(), we prevent simultaneous | * By holding the high-level sblock(), we prevent simultaneous | ||||
* readers from pulling off the front of the socket buffer. | * readers from pulling off the front of the socket buffer. | ||||
*/ | */ | ||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv); | SOCKBUF_LOCK_ASSERT(&so->so_rcv); | ||||
if (uio->uio_td) | if (uio->uio_td) | ||||
uio->uio_td->td_ru.ru_msgrcv++; | RU_ATOMIC_INC(uio->uio_td->td_ru.ru_msgrcv); | ||||
KASSERT(m == so->so_rcv.sb_mb, ("soreceive: m != so->so_rcv.sb_mb")); | KASSERT(m == so->so_rcv.sb_mb, ("soreceive: m != so->so_rcv.sb_mb")); | ||||
SBLASTRECORDCHK(&so->so_rcv); | SBLASTRECORDCHK(&so->so_rcv); | ||||
SBLASTMBUFCHK(&so->so_rcv); | SBLASTMBUFCHK(&so->so_rcv); | ||||
nextrecord = m->m_nextpkt; | nextrecord = m->m_nextpkt; | ||||
if (pr->pr_flags & PR_ADDR) { | if (pr->pr_flags & PR_ADDR) { | ||||
KASSERT(m->m_type == MT_SONAME, | KASSERT(m->m_type == MT_SONAME, | ||||
("m->m_type == %d", m->m_type)); | ("m->m_type == %d", m->m_type)); | ||||
orig_resid = 0; | orig_resid = 0; | ||||
▲ Show 20 Lines • Show All 475 Lines • ▼ Show 20 Lines | |||||
deliver: | deliver: | ||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv); | SOCKBUF_LOCK_ASSERT(&so->so_rcv); | ||||
KASSERT(sbavail(sb) > 0, ("%s: sockbuf empty", __func__)); | KASSERT(sbavail(sb) > 0, ("%s: sockbuf empty", __func__)); | ||||
KASSERT(sb->sb_mb != NULL, ("%s: sb_mb == NULL", __func__)); | KASSERT(sb->sb_mb != NULL, ("%s: sb_mb == NULL", __func__)); | ||||
/* Statistics. */ | /* Statistics. */ | ||||
if (uio->uio_td) | if (uio->uio_td) | ||||
uio->uio_td->td_ru.ru_msgrcv++; | RU_ATOMIC_INC(uio->uio_td->td_ru.ru_msgrcv); | ||||
/* Fill uio until full or current end of socket buffer is reached. */ | /* Fill uio until full or current end of socket buffer is reached. */ | ||||
len = min(uio->uio_resid, sbavail(sb)); | len = min(uio->uio_resid, sbavail(sb)); | ||||
if (mp0 != NULL) { | if (mp0 != NULL) { | ||||
/* Dequeue as many mbufs as possible. */ | /* Dequeue as many mbufs as possible. */ | ||||
if (!(flags & MSG_PEEK) && len >= sb->sb_mb->m_len) { | if (!(flags & MSG_PEEK) && len >= sb->sb_mb->m_len) { | ||||
if (*mp0 == NULL) | if (*mp0 == NULL) | ||||
*mp0 = sb->sb_mb; | *mp0 = sb->sb_mb; | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | while ((m = so->so_rcv.sb_mb) == NULL) { | ||||
if (error) { | if (error) { | ||||
SOCKBUF_UNLOCK(&so->so_rcv); | SOCKBUF_UNLOCK(&so->so_rcv); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv); | SOCKBUF_LOCK_ASSERT(&so->so_rcv); | ||||
if (uio->uio_td) | if (uio->uio_td) | ||||
uio->uio_td->td_ru.ru_msgrcv++; | RU_ATOMIC_INC(uio->uio_td->td_ru.ru_msgrcv); | ||||
SBLASTRECORDCHK(&so->so_rcv); | SBLASTRECORDCHK(&so->so_rcv); | ||||
SBLASTMBUFCHK(&so->so_rcv); | SBLASTMBUFCHK(&so->so_rcv); | ||||
nextrecord = m->m_nextpkt; | nextrecord = m->m_nextpkt; | ||||
if (nextrecord == NULL) { | if (nextrecord == NULL) { | ||||
KASSERT(so->so_rcv.sb_lastrecord == m, | KASSERT(so->so_rcv.sb_lastrecord == m, | ||||
("soreceive_dgram: lastrecord != m")); | ("soreceive_dgram: lastrecord != m")); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,777 Lines • Show Last 20 Lines |