git: b4a5ab97c810 - main - ctld: Factor out code to setup a listening socket into a separate function

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 24 Jan 2025 14:54:41 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=b4a5ab97c8104bd9e3f36b164b4648bf9dc6bc94

commit b4a5ab97c8104bd9e3f36b164b4648bf9dc6bc94
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-01-24 14:52:51 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-01-24 14:53:30 +0000

    ctld: Factor out code to setup a listening socket into a separate function
    
    While here:
    
    - Reuse the address family from the addrinfo structure instead of
      calling getsockname(2) on the socket.
    
    - Remove a bogus comment about the PCP option.
    
    Reviewed by:    mav, asomers
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D48596
---
 usr.sbin/ctld/ctld.c | 199 ++++++++++++++++++++++++---------------------------
 1 file changed, 94 insertions(+), 105 deletions(-)

diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c
index 93a749b9109a..a67ff51a451d 100644
--- a/usr.sbin/ctld/ctld.c
+++ b/usr.sbin/ctld/ctld.c
@@ -1806,6 +1806,98 @@ conf_verify(struct conf *conf)
 	return (0);
 }
 
+static bool
+portal_init_socket(struct portal *p)
+{
+	struct portal_group *pg = p->p_portal_group;
+	int error, sockbuf;
+	int one = 1;
+
+	log_debugx("listening on %s, portal-group \"%s\"",
+	    p->p_listen, pg->pg_name);
+	p->p_socket = socket(p->p_ai->ai_family, p->p_ai->ai_socktype,
+	    p->p_ai->ai_protocol);
+	if (p->p_socket < 0) {
+		log_warn("socket(2) failed for %s",
+		    p->p_listen);
+		return (false);
+	}
+
+	sockbuf = SOCKBUF_SIZE;
+	if (setsockopt(p->p_socket, SOL_SOCKET, SO_RCVBUF, &sockbuf,
+	    sizeof(sockbuf)) == -1)
+		log_warn("setsockopt(SO_RCVBUF) failed for %s",
+		    p->p_listen);
+	sockbuf = SOCKBUF_SIZE;
+	if (setsockopt(p->p_socket, SOL_SOCKET, SO_SNDBUF, &sockbuf,
+	    sizeof(sockbuf)) == -1)
+		log_warn("setsockopt(SO_SNDBUF) failed for %s", p->p_listen);
+	if (setsockopt(p->p_socket, SOL_SOCKET, SO_NO_DDP, &one,
+	    sizeof(one)) == -1)
+		log_warn("setsockopt(SO_NO_DDP) failed for %s", p->p_listen);
+	error = setsockopt(p->p_socket, SOL_SOCKET, SO_REUSEADDR, &one,
+	    sizeof(one));
+	if (error != 0) {
+		log_warn("setsockopt(SO_REUSEADDR) failed for %s", p->p_listen);
+		close(p->p_socket);
+		p->p_socket = 0;
+		return (false);
+	}
+
+	if (pg->pg_dscp != -1) {
+		/* Only allow the 6-bit DSCP field to be modified */
+		int tos = pg->pg_dscp << 2;
+		switch (p->p_ai->ai_family) {
+		case AF_INET:
+			if (setsockopt(p->p_socket, IPPROTO_IP, IP_TOS,
+			    &tos, sizeof(tos)) == -1)
+				log_warn("setsockopt(IP_TOS) failed for %s",
+				    p->p_listen);
+			break;
+		case AF_INET6:
+			if (setsockopt(p->p_socket, IPPROTO_IPV6, IPV6_TCLASS,
+			    &tos, sizeof(tos)) == -1)
+				log_warn("setsockopt(IPV6_TCLASS) failed for %s",
+				    p->p_listen);
+			break;
+		}
+	}
+	if (pg->pg_pcp != -1) {
+		int pcp = pg->pg_pcp;
+		switch (p->p_ai->ai_family) {
+		case AF_INET:
+			if (setsockopt(p->p_socket, IPPROTO_IP, IP_VLAN_PCP,
+			    &pcp, sizeof(pcp)) == -1)
+				log_warn("setsockopt(IP_VLAN_PCP) failed for %s",
+				    p->p_listen);
+			break;
+		case AF_INET6:
+			if (setsockopt(p->p_socket, IPPROTO_IPV6, IPV6_VLAN_PCP,
+			    &pcp, sizeof(pcp)) == -1)
+				log_warn("setsockopt(IPV6_VLAN_PCP) failed for %s",
+				    p->p_listen);
+			break;
+		}
+	}
+
+	error = bind(p->p_socket, p->p_ai->ai_addr,
+	    p->p_ai->ai_addrlen);
+	if (error != 0) {
+		log_warn("bind(2) failed for %s", p->p_listen);
+		close(p->p_socket);
+		p->p_socket = 0;
+		return (false);
+	}
+	error = listen(p->p_socket, -1);
+	if (error != 0) {
+		log_warn("listen(2) failed for %s", p->p_listen);
+		close(p->p_socket);
+		p->p_socket = 0;
+		return (false);
+	}
+	return (true);
+}
+
 static int
 conf_apply(struct conf *oldconf, struct conf *newconf)
 {
@@ -1814,8 +1906,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
 	struct portal *oldp, *newp;
 	struct port *oldport, *newport, *tmpport;
 	struct isns *oldns, *newns;
-	int changed, cumulated_error = 0, error, sockbuf;
-	int one = 1;
+	int changed, cumulated_error = 0, error;
 
 	if (oldconf->conf_debug != newconf->conf_debug) {
 		log_debugx("changing debug level to %d", newconf->conf_debug);
@@ -2082,109 +2173,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
 			assert(proxy_mode == false);
 			assert(newp->p_iser == false);
 
-			log_debugx("listening on %s, portal-group \"%s\"",
-			    newp->p_listen, newpg->pg_name);
-			newp->p_socket = socket(newp->p_ai->ai_family,
-			    newp->p_ai->ai_socktype,
-			    newp->p_ai->ai_protocol);
-			if (newp->p_socket < 0) {
-				log_warn("socket(2) failed for %s",
-				    newp->p_listen);
-				cumulated_error++;
-				continue;
-			}
-			sockbuf = SOCKBUF_SIZE;
-			if (setsockopt(newp->p_socket, SOL_SOCKET, SO_RCVBUF,
-			    &sockbuf, sizeof(sockbuf)) == -1)
-				log_warn("setsockopt(SO_RCVBUF) failed "
-				    "for %s", newp->p_listen);
-			sockbuf = SOCKBUF_SIZE;
-			if (setsockopt(newp->p_socket, SOL_SOCKET, SO_SNDBUF,
-			    &sockbuf, sizeof(sockbuf)) == -1)
-				log_warn("setsockopt(SO_SNDBUF) failed "
-				    "for %s", newp->p_listen);
-			if (setsockopt(newp->p_socket, SOL_SOCKET, SO_NO_DDP,
-			    &one, sizeof(one)) == -1)
-				log_warn("setsockopt(SO_NO_DDP) failed "
-				    "for %s", newp->p_listen);
-			error = setsockopt(newp->p_socket, SOL_SOCKET,
-			    SO_REUSEADDR, &one, sizeof(one));
-			if (error != 0) {
-				log_warn("setsockopt(SO_REUSEADDR) failed "
-				    "for %s", newp->p_listen);
-				close(newp->p_socket);
-				newp->p_socket = 0;
-				cumulated_error++;
-				continue;
-			}
-			if (newpg->pg_dscp != -1) {
-				struct sockaddr sa;
-				int len = sizeof(sa);
-				getsockname(newp->p_socket, &sa, &len);
-				/*
-				 * Only allow the 6-bit DSCP
-				 * field to be modified
-				 */
-				int tos = newpg->pg_dscp << 2;
-				if (sa.sa_family == AF_INET) {
-					if (setsockopt(newp->p_socket,
-					    IPPROTO_IP, IP_TOS,
-					    &tos, sizeof(tos)) == -1)
-						log_warn("setsockopt(IP_TOS) "
-						    "failed for %s",
-						    newp->p_listen);
-				} else
-				if (sa.sa_family == AF_INET6) {
-					if (setsockopt(newp->p_socket,
-					    IPPROTO_IPV6, IPV6_TCLASS,
-					    &tos, sizeof(tos)) == -1)
-						log_warn("setsockopt(IPV6_TCLASS) "
-						    "failed for %s",
-						    newp->p_listen);
-				}
-			}
-			if (newpg->pg_pcp != -1) {
-				struct sockaddr sa;
-				int len = sizeof(sa);
-				getsockname(newp->p_socket, &sa, &len);
-				/*
-				 * Only allow the 6-bit DSCP
-				 * field to be modified
-				 */
-				int pcp = newpg->pg_pcp;
-				if (sa.sa_family == AF_INET) {
-					if (setsockopt(newp->p_socket,
-					    IPPROTO_IP, IP_VLAN_PCP,
-					    &pcp, sizeof(pcp)) == -1)
-						log_warn("setsockopt(IP_VLAN_PCP) "
-						    "failed for %s",
-						    newp->p_listen);
-				} else
-				if (sa.sa_family == AF_INET6) {
-					if (setsockopt(newp->p_socket,
-					    IPPROTO_IPV6, IPV6_VLAN_PCP,
-					    &pcp, sizeof(pcp)) == -1)
-						log_warn("setsockopt(IPV6_VLAN_PCP) "
-						    "failed for %s",
-						    newp->p_listen);
-				}
-			}
-			error = bind(newp->p_socket, newp->p_ai->ai_addr,
-			    newp->p_ai->ai_addrlen);
-			if (error != 0) {
-				log_warn("bind(2) failed for %s",
-				    newp->p_listen);
-				close(newp->p_socket);
-				newp->p_socket = 0;
-				cumulated_error++;
-				continue;
-			}
-			error = listen(newp->p_socket, -1);
-			if (error != 0) {
-				log_warn("listen(2) failed for %s",
-				    newp->p_listen);
-				close(newp->p_socket);
-				newp->p_socket = 0;
+			if (!portal_init_socket(newp)) {
 				cumulated_error++;
 				continue;
 			}