Increase the default buffer space using on PF_UNIX sockets to 8k.
authorclaudio <claudio@openbsd.org>
Mon, 17 May 2021 17:06:51 +0000 (17:06 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 17 May 2021 17:06:51 +0000 (17:06 +0000)
Additionally make the values tuneable via sysctl.
OK deraadt@ mvs@

sys/kern/uipc_domain.c
sys/kern/uipc_usrreq.c
sys/net/rtsock.c

index 8cb2c77..6dbbe01 100644 (file)
@@ -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,
index c1e766c..5a51fd6 100644 (file)
@@ -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 <sys/pledge.h>
 #include <sys/pool.h>
 #include <sys/rwlock.h>
+#include <sys/sysctl.h>
 
 /*
  * 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)
 {
index 3a1cf04..c514629 100644 (file)
@@ -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;