Provide sbsetopt() that handles socket buffer related socket options.
It distinguishes between data flow sockets and listening sockets, and in case of the latter doesn't change resource limits, since listening sockets don't hold any buffers, they only carry values to be inherited by their children.
This commit is contained in:
parent
2d44649837
commit
64290befc1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320324
@ -451,14 +451,78 @@ sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
|
sbsetopt(struct socket *so, int cmd, u_long cc)
|
||||||
struct thread *td)
|
|
||||||
{
|
{
|
||||||
|
struct sockbuf *sb;
|
||||||
|
short *flags;
|
||||||
|
u_int *hiwat, *lowat;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
SOCKBUF_LOCK(sb);
|
SOCK_LOCK(so);
|
||||||
error = sbreserve_locked(sb, cc, so, td);
|
if (SOLISTENING(so)) {
|
||||||
SOCKBUF_UNLOCK(sb);
|
switch (cmd) {
|
||||||
|
case SO_SNDLOWAT:
|
||||||
|
case SO_SNDBUF:
|
||||||
|
lowat = &so->sol_sbsnd_lowat;
|
||||||
|
hiwat = &so->sol_sbsnd_hiwat;
|
||||||
|
flags = &so->sol_sbsnd_flags;
|
||||||
|
break;
|
||||||
|
case SO_RCVLOWAT:
|
||||||
|
case SO_RCVBUF:
|
||||||
|
lowat = &so->sol_sbrcv_lowat;
|
||||||
|
hiwat = &so->sol_sbrcv_hiwat;
|
||||||
|
flags = &so->sol_sbrcv_flags;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (cmd) {
|
||||||
|
case SO_SNDLOWAT:
|
||||||
|
case SO_SNDBUF:
|
||||||
|
sb = &so->so_snd;
|
||||||
|
break;
|
||||||
|
case SO_RCVLOWAT:
|
||||||
|
case SO_RCVBUF:
|
||||||
|
sb = &so->so_rcv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
flags = &sb->sb_flags;
|
||||||
|
hiwat = &sb->sb_hiwat;
|
||||||
|
lowat = &sb->sb_lowat;
|
||||||
|
SOCKBUF_LOCK(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
switch (cmd) {
|
||||||
|
case SO_SNDBUF:
|
||||||
|
case SO_RCVBUF:
|
||||||
|
if (SOLISTENING(so)) {
|
||||||
|
if (cc > sb_max_adj) {
|
||||||
|
error = ENOBUFS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*hiwat = cc;
|
||||||
|
if (*lowat > *hiwat)
|
||||||
|
*lowat = *hiwat;
|
||||||
|
} else {
|
||||||
|
if (!sbreserve_locked(sb, cc, so, curthread))
|
||||||
|
error = ENOBUFS;
|
||||||
|
}
|
||||||
|
if (error == 0)
|
||||||
|
*flags &= ~SB_AUTOSIZE;
|
||||||
|
break;
|
||||||
|
case SO_SNDLOWAT:
|
||||||
|
case SO_RCVLOWAT:
|
||||||
|
/*
|
||||||
|
* Make sure the low-water is never greater than the
|
||||||
|
* high-water.
|
||||||
|
*/
|
||||||
|
*lowat = (cc > *hiwat) ? *hiwat : cc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SOLISTENING(so))
|
||||||
|
SOCKBUF_UNLOCK(sb);
|
||||||
|
SOCK_UNLOCK(so);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,12 +461,6 @@ sodealloc(struct socket *so)
|
|||||||
so->so_vnet->vnet_sockcnt--;
|
so->so_vnet->vnet_sockcnt--;
|
||||||
#endif
|
#endif
|
||||||
mtx_unlock(&so_global_mtx);
|
mtx_unlock(&so_global_mtx);
|
||||||
if (so->so_rcv.sb_hiwat)
|
|
||||||
(void)chgsbsize(so->so_cred->cr_uidinfo,
|
|
||||||
&so->so_rcv.sb_hiwat, 0, RLIM_INFINITY);
|
|
||||||
if (so->so_snd.sb_hiwat)
|
|
||||||
(void)chgsbsize(so->so_cred->cr_uidinfo,
|
|
||||||
&so->so_snd.sb_hiwat, 0, RLIM_INFINITY);
|
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
mac_socket_destroy(so);
|
mac_socket_destroy(so);
|
||||||
#endif
|
#endif
|
||||||
@ -478,6 +472,12 @@ sodealloc(struct socket *so)
|
|||||||
if (so->sol_accept_filter != NULL)
|
if (so->sol_accept_filter != NULL)
|
||||||
accept_filt_setopt(so, NULL);
|
accept_filt_setopt(so, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
if (so->so_rcv.sb_hiwat)
|
||||||
|
(void)chgsbsize(so->so_cred->cr_uidinfo,
|
||||||
|
&so->so_rcv.sb_hiwat, 0, RLIM_INFINITY);
|
||||||
|
if (so->so_snd.sb_hiwat)
|
||||||
|
(void)chgsbsize(so->so_cred->cr_uidinfo,
|
||||||
|
&so->so_snd.sb_hiwat, 0, RLIM_INFINITY);
|
||||||
sx_destroy(&so->so_snd.sb_sx);
|
sx_destroy(&so->so_snd.sb_sx);
|
||||||
sx_destroy(&so->so_rcv.sb_sx);
|
sx_destroy(&so->so_rcv.sb_sx);
|
||||||
SOCKBUF_LOCK_DESTROY(&so->so_snd);
|
SOCKBUF_LOCK_DESTROY(&so->so_snd);
|
||||||
@ -2834,38 +2834,7 @@ sosetopt(struct socket *so, struct sockopt *sopt)
|
|||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sopt->sopt_name) {
|
error = sbsetopt(so, sopt->sopt_name, optval);
|
||||||
case SO_SNDBUF:
|
|
||||||
case SO_RCVBUF:
|
|
||||||
if (sbreserve(sopt->sopt_name == SO_SNDBUF ?
|
|
||||||
&so->so_snd : &so->so_rcv, (u_long)optval,
|
|
||||||
so, curthread) == 0) {
|
|
||||||
error = ENOBUFS;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
(sopt->sopt_name == SO_SNDBUF ? &so->so_snd :
|
|
||||||
&so->so_rcv)->sb_flags &= ~SB_AUTOSIZE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure the low-water is never greater than the
|
|
||||||
* high-water.
|
|
||||||
*/
|
|
||||||
case SO_SNDLOWAT:
|
|
||||||
SOCKBUF_LOCK(&so->so_snd);
|
|
||||||
so->so_snd.sb_lowat =
|
|
||||||
(optval > so->so_snd.sb_hiwat) ?
|
|
||||||
so->so_snd.sb_hiwat : optval;
|
|
||||||
SOCKBUF_UNLOCK(&so->so_snd);
|
|
||||||
break;
|
|
||||||
case SO_RCVLOWAT:
|
|
||||||
SOCKBUF_LOCK(&so->so_rcv);
|
|
||||||
so->so_rcv.sb_lowat =
|
|
||||||
(optval > so->so_rcv.sb_hiwat) ?
|
|
||||||
so->so_rcv.sb_hiwat : optval;
|
|
||||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SO_SNDTIMEO:
|
case SO_SNDTIMEO:
|
||||||
|
@ -167,8 +167,7 @@ void sbflush_locked(struct sockbuf *sb);
|
|||||||
void sbrelease(struct sockbuf *sb, struct socket *so);
|
void sbrelease(struct sockbuf *sb, struct socket *so);
|
||||||
void sbrelease_internal(struct sockbuf *sb, struct socket *so);
|
void sbrelease_internal(struct sockbuf *sb, struct socket *so);
|
||||||
void sbrelease_locked(struct sockbuf *sb, struct socket *so);
|
void sbrelease_locked(struct sockbuf *sb, struct socket *so);
|
||||||
int sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
|
int sbsetopt(struct socket *so, int cmd, u_long cc);
|
||||||
struct thread *td);
|
|
||||||
int sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
|
int sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
|
||||||
struct thread *td);
|
struct thread *td);
|
||||||
struct mbuf *
|
struct mbuf *
|
||||||
|
Loading…
Reference in New Issue
Block a user