aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2024-11-14 16:05:27 +0000
committerMark Johnston <markj@FreeBSD.org>2024-11-14 16:05:27 +0000
commit45a77bf23fa2f36bf2169f7ba2a33b31f4c35adb (patch)
treef93c53a904985aaae8146d7bbbd94fd360aa97f6
parent02dc158215a69c6439e5a0809e5f9c79e62c5fd1 (diff)
inpcb: Make some cosmetic improvements to in_pcbbind()
- Use the local var "laddr" instead of sin->sin_addr in one block. - Use in_nullhost() instead of explicit comparisons with INADDR_ANY. - Combine multiple socket options checks into one. - Fix indentation. - Remove some unhelpful comments. This is in preparation for some simplification and bug-fixing. No functional change intended. Reviewed by: glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D47451
-rw-r--r--sys/netinet/in_pcb.c44
-rw-r--r--sys/netinet6/in6_pcb.c19
2 files changed, 28 insertions, 35 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 769724fd5063..116ee149fecb 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -916,8 +916,10 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
return (EINVAL);
lport = sin->sin_port;
}
+ laddr = sin->sin_addr;
+
/* NB: lport is left as 0 if the port isn't being changed. */
- if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
+ if (IN_MULTICAST(ntohl(laddr.s_addr))) {
/*
* Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
* allow complete duplication of binding if
@@ -934,7 +936,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
if ((so->so_options &
(SO_REUSEADDR|SO_REUSEPORT_LB)) != 0)
reuseport_lb = SO_REUSEADDR|SO_REUSEPORT_LB;
- } else if (sin->sin_addr.s_addr != INADDR_ANY) {
+ } else if (!in_nullhost(laddr)) {
sin->sin_port = 0; /* yech... */
bzero(&sin->sin_zero, sizeof(sin->sin_zero));
/*
@@ -943,50 +945,44 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
* to any endpoint address, local or not.
*/
if ((inp->inp_flags & INP_BINDANY) == 0 &&
- ifa_ifwithaddr_check((struct sockaddr *)sin) == 0)
+ ifa_ifwithaddr_check(
+ (const struct sockaddr *)sin) == 0)
return (EADDRNOTAVAIL);
}
- laddr = sin->sin_addr;
if (lport) {
struct inpcb *t;
- /* GROSS */
if (ntohs(lport) <= V_ipport_reservedhigh &&
ntohs(lport) >= V_ipport_reservedlow &&
priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
return (EACCES);
- if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
+
+ if (!IN_MULTICAST(ntohl(laddr.s_addr)) &&
priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 0) {
- t = in_pcblookup_local(pcbinfo, sin->sin_addr,
- lport, INPLOOKUP_WILDCARD, cred);
- /*
- * XXX
- * This entire block sorely needs a rewrite.
- */
+ t = in_pcblookup_local(pcbinfo, laddr, lport,
+ INPLOOKUP_WILDCARD, cred);
if (t != NULL &&
(so->so_type != SOCK_STREAM ||
- ntohl(t->inp_faddr.s_addr) == INADDR_ANY) &&
- (ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
- ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
+ in_nullhost(t->inp_faddr)) &&
+ (!in_nullhost(laddr) ||
+ !in_nullhost(t->inp_laddr) ||
(t->inp_socket->so_options & SO_REUSEPORT) ||
(t->inp_socket->so_options & SO_REUSEPORT_LB) == 0) &&
(inp->inp_cred->cr_uid !=
t->inp_cred->cr_uid))
return (EADDRINUSE);
}
- t = in_pcblookup_local(pcbinfo, sin->sin_addr,
- lport, lookupflags, cred);
- if (t != NULL && (reuseport & t->inp_socket->so_options) == 0 &&
- (reuseport_lb & t->inp_socket->so_options) == 0) {
+ t = in_pcblookup_local(pcbinfo, laddr, lport,
+ lookupflags, cred);
+ if (t != NULL && ((reuseport | reuseport_lb) &
+ t->inp_socket->so_options) == 0) {
#ifdef INET6
- if (ntohl(sin->sin_addr.s_addr) !=
- INADDR_ANY ||
- ntohl(t->inp_laddr.s_addr) !=
- INADDR_ANY ||
+ if (!in_nullhost(laddr) ||
+ !in_nullhost(t->inp_laddr) ||
(inp->inp_vflag & INP_IPV6PROTO) == 0 ||
(t->inp_vflag & INP_IPV6PROTO) == 0)
#endif
- return (EADDRINUSE);
+ return (EADDRINUSE);
}
}
}
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 49a430ea6d01..45fdd6541bf7 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -247,11 +247,11 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
if (lport) {
struct inpcb *t;
- /* GROSS */
if (ntohs(lport) <= V_ipport_reservedhigh &&
ntohs(lport) >= V_ipport_reservedlow &&
priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
return (EACCES);
+
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 0) {
t = in6_pcblookup_local(pcbinfo,
@@ -279,8 +279,7 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
INPLOOKUP_WILDCARD, cred);
if (t != NULL &&
(so->so_type != SOCK_STREAM ||
- ntohl(t->inp_faddr.s_addr) ==
- INADDR_ANY) &&
+ in_nullhost(t->inp_faddr)) &&
(inp->inp_cred->cr_uid !=
t->inp_cred->cr_uid))
return (EADDRINUSE);
@@ -289,10 +288,9 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
}
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
lport, lookupflags, cred);
- if (t && (reuseport & t->inp_socket->so_options) == 0 &&
- (reuseport_lb & t->inp_socket->so_options) == 0) {
+ if (t != NULL && ((reuseport | reuseport_lb) &
+ t->inp_socket->so_options) == 0)
return (EADDRINUSE);
- }
#ifdef INET
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
@@ -301,11 +299,10 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
in6_sin6_2_sin(&sin, sin6);
t = in_pcblookup_local(pcbinfo, sin.sin_addr,
lport, lookupflags, cred);
- if (t &&
- (reuseport & t->inp_socket->so_options) == 0 &&
- (reuseport_lb & t->inp_socket->so_options) == 0 &&
- (ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
- (t->inp_vflag & INP_IPV6PROTO) != 0)) {
+ if (t != NULL && ((reuseport | reuseport_lb) &
+ t->inp_socket->so_options) == 0 &&
+ (!in_nullhost(t->inp_laddr) ||
+ (t->inp_vflag & INP_IPV6PROTO) != 0)) {
return (EADDRINUSE);
}
}