From c7f1aac795a1e2eb81178160cd39b8c9e3313b52 Mon Sep 17 00:00:00 2001 From: claudio Date: Mon, 17 May 2021 17:06:51 +0000 Subject: [PATCH] Increase the default buffer space using on PF_UNIX sockets to 8k. Additionally make the values tuneable via sysctl. OK deraadt@ mvs@ --- sys/kern/uipc_domain.c | 5 ++- sys/kern/uipc_usrreq.c | 68 +++++++++++++++++++++++++++++++---- sys/net/rtsock.c | 82 +++++++++++++++++++++++++++++++++++------- 3 files changed, 134 insertions(+), 21 deletions(-) diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 8cb2c77dc60..6dbbe01921c 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_domain.c,v 1.57 2019/07/03 10:19:45 dlg Exp $ */ +/* $OpenBSD: uipc_domain.c,v 1.58 2021/05/17 17:06:51 claudio Exp $ */ /* $NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $ */ /* @@ -212,6 +212,9 @@ net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, if (family == PF_LINK) return (net_link_sysctl(name + 1, namelen - 1, oldp, oldlenp, newp, newlen)); + if (family == PF_UNIX) + return (uipc_sysctl(name + 1, namelen - 1, oldp, oldlenp, + newp, newlen)); #if NBPFILTER > 0 if (family == PF_BPF) return (bpf_sysctl(name + 1, namelen - 1, oldp, oldlenp, diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index c1e766cf0b6..5a51fd6d7f6 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.145 2021/04/29 20:13:25 mvs Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.146 2021/05/17 17:06:51 claudio Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -52,6 +52,7 @@ #include #include #include +#include /* * Locks used to protect global data and struct members: @@ -354,11 +355,26 @@ release: * and don't really want to reserve the sendspace. Their recvspace should * be large enough for at least one max-size datagram plus address. */ -#define PIPSIZ 4096 -u_long unpst_sendspace = PIPSIZ; -u_long unpst_recvspace = PIPSIZ; -u_long unpdg_sendspace = 2*1024; /* really max datagram size */ -u_long unpdg_recvspace = 4*1024; +#define PIPSIZ 8192 +u_int unpst_sendspace = PIPSIZ; +u_int unpst_recvspace = PIPSIZ; +u_int unpsq_sendspace = PIPSIZ; +u_int unpsq_recvspace = PIPSIZ; +u_int unpdg_sendspace = 2*1024; /* really max datagram size */ +u_int unpdg_recvspace = 16*1024; + +const struct sysctl_bounded_args unpstctl_vars[] = { + { UNPCTL_RECVSPACE, &unpst_recvspace, 0, SB_MAX }, + { UNPCTL_SENDSPACE, &unpst_sendspace, 0, SB_MAX }, +}; +const struct sysctl_bounded_args unpsqctl_vars[] = { + { UNPCTL_RECVSPACE, &unpsq_recvspace, 0, SB_MAX }, + { UNPCTL_SENDSPACE, &unpsq_sendspace, 0, SB_MAX }, +}; +const struct sysctl_bounded_args unpdgctl_vars[] = { + { UNPCTL_RECVSPACE, &unpdg_recvspace, 0, SB_MAX }, + { UNPCTL_SENDSPACE, &unpdg_sendspace, 0, SB_MAX }, +}; int uipc_attach(struct socket *so, int proto) @@ -374,10 +390,13 @@ uipc_attach(struct socket *so, int proto) switch (so->so_type) { case SOCK_STREAM: - case SOCK_SEQPACKET: error = soreserve(so, unpst_sendspace, unpst_recvspace); break; + case SOCK_SEQPACKET: + error = soreserve(so, unpsq_sendspace, unpsq_recvspace); + break; + case SOCK_DGRAM: error = soreserve(so, unpdg_sendspace, unpdg_recvspace); break; @@ -411,6 +430,41 @@ uipc_detach(struct socket *so) return (0); } +int +uipc_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, + size_t newlen) +{ + int *valp = &unp_defer; + + /* All sysctl names at this level are terminal. */ + switch (name[0]) { + case SOCK_STREAM: + if (namelen != 2) + return (ENOTDIR); + return sysctl_bounded_arr(unpstctl_vars, nitems(unpstctl_vars), + name + 1, namelen - 1, oldp, oldlenp, newp, newlen); + case SOCK_SEQPACKET: + if (namelen != 2) + return (ENOTDIR); + return sysctl_bounded_arr(unpsqctl_vars, nitems(unpsqctl_vars), + name + 1, namelen - 1, oldp, oldlenp, newp, newlen); + case SOCK_DGRAM: + if (namelen != 2) + return (ENOTDIR); + return sysctl_bounded_arr(unpdgctl_vars, nitems(unpdgctl_vars), + name + 1, namelen - 1, oldp, oldlenp, newp, newlen); + case NET_UNIX_INFLIGHT: + valp = &unp_rights; + /* FALLTHOUGH */ + case NET_UNIX_DEFERRED: + if (namelen != 1) + return (ENOTDIR); + return sysctl_rdint(oldp, oldlenp, newp, *valp); + default: + return (ENOPROTOOPT); + } +} + void unp_detach(struct unpcb *unp) { diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 3a1cf04f8ac..c514629a407 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.313 2021/05/16 13:09:39 mvs Exp $ */ +/* $OpenBSD: rtsock.c,v 1.314 2021/05/17 17:06:51 claudio Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -124,10 +124,12 @@ int rtm_getifa(struct rt_addrinfo *, unsigned int); int rtm_output(struct rt_msghdr *, struct rtentry **, struct rt_addrinfo *, uint8_t, unsigned int); struct rt_msghdr *rtm_report(struct rtentry *, u_char, int, int); +int rtm_embedscope(struct sockaddr *); +void rtm_recoverscope(struct sockaddr *); +int rtm_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); struct mbuf *rtm_msg1(int, struct rt_addrinfo *); int rtm_msg2(int, int, struct rt_addrinfo *, caddr_t, struct walkarg *); -int rtm_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); int rtm_validate_proposal(struct rt_addrinfo *); void rtm_setmetrics(u_long, const struct rt_metrics *, struct rt_kmetrics *); @@ -1379,6 +1381,47 @@ rtm_getmetrics(const struct rt_kmetrics *in, struct rt_metrics *out) out->rmx_pksent = in->rmx_pksent; } +int +rtm_embedscope(struct sockaddr *sa) +{ +#ifdef INET6 + struct sockaddr_in6 *sin6; + struct in6_addr in6; + int error; + + if (sa->sa_family == AF_INET6) { + sin6 = satosin6(sa); + if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr)) { + error = in6_embedscope(&in6, sin6, NULL); + if (error) + return error; + sin6->sin6_addr = in6; + sin6->sin6_scope_id = 0; + } + } +#endif + return 0; +} +void +rtm_recoverscope(struct sockaddr *sa) +{ +#ifdef INET6 + struct sockaddr_in6 *sin6; + + if (sa->sa_family == AF_INET6) { + sin6 = satosin6(sa); + if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr) && + sin6->sin6_scope_id == 0) { + u_int32_t scopeid = ntohs(sin6->sin6_addr.s6_addr16[1]); + if (scopeid) { + sin6->sin6_addr.s6_addr16[1] = 0; + sin6->sin6_scope_id = scopeid; + } + } + } +#endif +} + #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) @@ -1387,7 +1430,7 @@ int rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) { struct sockaddr *sa; - int i; + int i, error; /* * Parse address bits, split address storage in chunks, and @@ -1518,8 +1561,9 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) len = strnlen(sa->sa_data, maxlen); if (len >= maxlen || 2 + len >= sa->sa_len) return (EINVAL); - break; } + if ((error = rtm_embedscope(sa)) != 0) + return (error); } return (0); } @@ -1536,26 +1580,32 @@ rtm_msg1(int type, struct rt_addrinfo *rtinfo) switch (type) { case RTM_DELADDR: case RTM_NEWADDR: - len = sizeof(struct ifa_msghdr); + hlen = sizeof(struct ifa_msghdr); break; case RTM_IFINFO: - len = sizeof(struct if_msghdr); + hlen = sizeof(struct if_msghdr); break; case RTM_IFANNOUNCE: - len = sizeof(struct if_announcemsghdr); + hlen = sizeof(struct if_announcemsghdr); break; #ifdef BFD case RTM_BFD: - len = sizeof(struct bfd_msghdr); + hlen = sizeof(struct bfd_msghdr); break; #endif case RTM_80211INFO: - len = sizeof(struct if_ieee80211_msghdr); + hlen = sizeof(struct if_ieee80211_msghdr); break; default: - len = sizeof(struct rt_msghdr); + hlen = sizeof(struct rt_msghdr); break; } + len = hlen; + for (i = 0; i < RTAX_MAX; i++) { + if (rtinfo == NULL || (sa = rtinfo->rti_info[i]) == NULL) + continue; + len += ROUNDUP(sa->sa_len); + } if (len > MCLBYTES) panic("rtm_msg1"); m = m_gethdr(M_DONTWAIT, MT_DATA); @@ -1568,19 +1618,23 @@ rtm_msg1(int type, struct rt_addrinfo *rtinfo) } if (m == NULL) return (m); - m->m_pkthdr.len = m->m_len = hlen = len; + m->m_pkthdr.len = m->m_len = len; m->m_pkthdr.ph_ifidx = 0; rtm = mtod(m, struct rt_msghdr *); bzero(rtm, len); + len = hlen; for (i = 0; i < RTAX_MAX; i++) { + caddr_t cp; if (rtinfo == NULL || (sa = rtinfo->rti_info[i]) == NULL) continue; rtinfo->rti_addrs |= (1 << i); dlen = ROUNDUP(sa->sa_len); - if (m_copyback(m, len, dlen, sa, M_NOWAIT)) { + if (m_copyback(m, len, sa->sa_len, sa, M_NOWAIT)) { m_freem(m); return (NULL); } + cp = mtod(m, caddr_t) + len; + rtm_recoverscope((struct sockaddr *)cp); len += dlen; } rtm->rtm_msglen = len; @@ -1623,7 +1677,9 @@ again: rtinfo->rti_addrs |= (1 << i); dlen = ROUNDUP(sa->sa_len); if (cp) { - bcopy(sa, cp, (size_t)dlen); + bcopy(sa, cp, sa->sa_len); + bzero(cp + sa->sa_len, dlen - sa->sa_len); + rtm_recoverscope((struct sockaddr *)cp); cp += dlen; } len += dlen; -- 2.20.1