svn commit: r362451 - in head: lib/libc/net sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Sat Jun 20 21:06:03 UTC 2020


Author: tuexen
Date: Sat Jun 20 21:06:02 2020
New Revision: 362451
URL: https://svnweb.freebsd.org/changeset/base/362451

Log:
  Use a struct sockaddr_in pr struct sockaddr_in6 as the option value
  for the IPPROTO_SCTP level socket options SCTP_BINDX_ADD_ADDR and
  SCTP_BINDX_REM_ADDR. These socket option are intended for internal
  use only to implement sctp_bindx().
  This is one user of struct sctp_getaddresses less.
  struct sctp_getaddresses is strange and will be changed shortly.

Modified:
  head/lib/libc/net/sctp_sys_calls.c
  head/sys/netinet/sctp_usrreq.c

Modified: head/lib/libc/net/sctp_sys_calls.c
==============================================================================
--- head/lib/libc/net/sctp_sys_calls.c	Sat Jun 20 20:25:39 2020	(r362450)
+++ head/lib/libc/net/sctp_sys_calls.c	Sat Jun 20 21:06:02 2020	(r362451)
@@ -35,6 +35,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
@@ -170,13 +171,12 @@ sctp_connectx(int sd, const struct sockaddr *addrs, in
 int
 sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags)
 {
-	struct sctp_getaddresses *gaddrs;
 	struct sockaddr *sa;
 	struct sockaddr_in *sin;
 	struct sockaddr_in6 *sin6;
 	int i;
-	size_t argsz;
-	uint16_t sport = 0;
+	uint16_t sport;
+	bool fix_port;
 
 	/* validate the flags */
 	if ((flags != SCTP_BINDX_ADD_ADDR) &&
@@ -189,6 +189,8 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt
 		errno = EINVAL;
 		return (-1);
 	}
+	sport = 0;
+	fix_port = false;
 	/* First pre-screen the addresses */
 	sa = addrs;
 	for (i = 0; i < addrcnt; i++) {
@@ -210,6 +212,7 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt
 				} else {
 					/* save off the port */
 					sport = sin->sin_port;
+					fix_port = (i > 0);
 				}
 			}
 			break;
@@ -230,6 +233,7 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt
 				} else {
 					/* save off the port */
 					sport = sin6->sin6_port;
+					fix_port = (i > 0);
 				}
 			}
 			break;
@@ -240,42 +244,29 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt
 		}
 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
 	}
-	argsz = sizeof(struct sctp_getaddresses) +
-	    sizeof(struct sockaddr_storage);
-	if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) {
-		errno = ENOMEM;
-		return (-1);
-	}
 	sa = addrs;
 	for (i = 0; i < addrcnt; i++) {
-		memset(gaddrs, 0, argsz);
-		gaddrs->sget_assoc_id = 0;
-		memcpy(gaddrs->addr, sa, sa->sa_len);
 		/*
 		 * Now, if there was a port mentioned, assure that the first
 		 * address has that port to make sure it fails or succeeds
 		 * correctly.
 		 */
-		if ((i == 0) && (sport != 0)) {
-			switch (gaddrs->addr->sa_family) {
+		if (fix_port) {
+			switch (sa->sa_family) {
 			case AF_INET:
-				sin = (struct sockaddr_in *)gaddrs->addr;
-				sin->sin_port = sport;
+				((struct sockaddr_in *)sa)->sin_port = sport;
 				break;
 			case AF_INET6:
-				sin6 = (struct sockaddr_in6 *)gaddrs->addr;
-				sin6->sin6_port = sport;
+				((struct sockaddr_in6 *)sa)->sin6_port = sport;
 				break;
 			}
+			fix_port = false;
 		}
-		if (setsockopt(sd, IPPROTO_SCTP, flags, gaddrs,
-		    (socklen_t)argsz) != 0) {
-			free(gaddrs);
+		if (setsockopt(sd, IPPROTO_SCTP, flags, sa, sa->sa_len) != 0) {
 			return (-1);
 		}
 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
 	}
-	free(gaddrs);
 	return (0);
 }
 

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Sat Jun 20 20:25:39 2020	(r362450)
+++ head/sys/netinet/sctp_usrreq.c	Sat Jun 20 21:06:02 2020	(r362451)
@@ -5995,33 +5995,35 @@ sctp_setopt(struct socket *so, int optname, void *optv
 		}
 	case SCTP_BINDX_ADD_ADDR:
 		{
-			struct sctp_getaddresses *addrs;
+			struct sockaddr *sa;
 			struct thread *td;
 
 			td = (struct thread *)p;
-			SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses,
-			    optsize);
+			SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
 #ifdef INET
-			if (addrs->addr->sa_family == AF_INET) {
-				if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) {
+			if (sa->sa_family == AF_INET) {
+				if (optsize < sizeof(struct sockaddr_in)) {
 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 					error = EINVAL;
 					break;
 				}
-				if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) {
+				if (td != NULL &&
+				    (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)sa)->sin_addr)))) {
 					SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
 					break;
 				}
 			} else
 #endif
 #ifdef INET6
-			if (addrs->addr->sa_family == AF_INET6) {
-				if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) {
+			if (sa->sa_family == AF_INET6) {
+				if (optsize < sizeof(struct sockaddr_in6)) {
 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 					error = EINVAL;
 					break;
 				}
-				if (td != NULL && (error = prison_local_ip6(td->td_ucred, &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr),
+				if (td != NULL &&
+				    (error = prison_local_ip6(td->td_ucred,
+				    &(((struct sockaddr_in6 *)sa)->sin6_addr),
 				    (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
 					SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
 					break;
@@ -6032,40 +6034,41 @@ sctp_setopt(struct socket *so, int optname, void *optv
 				error = EAFNOSUPPORT;
 				break;
 			}
-			sctp_bindx_add_address(so, inp, addrs->addr, vrf_id, &error, p);
+			sctp_bindx_add_address(so, inp, sa, vrf_id, &error, p);
 			break;
 		}
 	case SCTP_BINDX_REM_ADDR:
 		{
-			struct sctp_getaddresses *addrs;
+			struct sockaddr *sa;
 			struct thread *td;
 
 			td = (struct thread *)p;
 
-			SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize);
+			SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
 #ifdef INET
-			if (addrs->addr->sa_family == AF_INET) {
-				if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) {
+			if (sa->sa_family == AF_INET) {
+				if (optsize < sizeof(struct sockaddr_in)) {
 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 					error = EINVAL;
 					break;
 				}
-				if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) {
+				if (td != NULL &&
+				    (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)sa)->sin_addr)))) {
 					SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
 					break;
 				}
 			} else
 #endif
 #ifdef INET6
-			if (addrs->addr->sa_family == AF_INET6) {
-				if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) {
+			if (sa->sa_family == AF_INET6) {
+				if (optsize < sizeof(struct sockaddr_in6)) {
 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 					error = EINVAL;
 					break;
 				}
 				if (td != NULL &&
 				    (error = prison_local_ip6(td->td_ucred,
-				    &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr),
+				    &(((struct sockaddr_in6 *)sa)->sin6_addr),
 				    (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
 					SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
 					break;
@@ -6076,7 +6079,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
 				error = EAFNOSUPPORT;
 				break;
 			}
-			sctp_bindx_delete_address(inp, addrs->addr, vrf_id, &error);
+			sctp_bindx_delete_address(inp, sa, vrf_id, &error);
 			break;
 		}
 	case SCTP_EVENT:


More information about the svn-src-all mailing list