Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Aug 2020 08:25:00 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r364620 - in stable/12: lib/libc/net sys/netinet
Message-ID:  <202008240825.07O8P0F5070954@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Mon Aug 24 08:25:00 2020
New Revision: 364620
URL: https://svnweb.freebsd.org/changeset/base/364620

Log:
  MFC r362473:
  leanup the defintion of struct sctp_getaddresses. This stucture
  is used by the IPPROTO_SCTP level socket options SCTP_GET_PEER_ADDRESSES
  and SCTP_GET_LOCAL_ADDRESSES, which are used by libc to implement
  sctp_getladdrs() and sctp_getpaddrs().
  These changes allow an old libc to work on a newer kernel.

Modified:
  stable/12/lib/libc/net/sctp_sys_calls.c
  stable/12/sys/netinet/sctp_uio.h
  stable/12/sys/netinet/sctp_usrreq.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/lib/libc/net/sctp_sys_calls.c
==============================================================================
--- stable/12/lib/libc/net/sctp_sys_calls.c	Mon Aug 24 08:22:37 2020	(r364619)
+++ stable/12/lib/libc/net/sctp_sys_calls.c	Mon Aug 24 08:25:00 2020	(r364620)
@@ -406,7 +406,7 @@ sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockadd
 		return (-1);
 	}
 	/* size required is returned in 'asoc' */
-	opt_len = (socklen_t)((size_t)asoc + sizeof(sctp_assoc_t));
+	opt_len = (socklen_t)((size_t)asoc + sizeof(struct sctp_getaddresses));
 	addrs = calloc(1, (size_t)opt_len);
 	if (addrs == NULL) {
 		errno = ENOMEM;
@@ -419,9 +419,9 @@ sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockadd
 		free(addrs);
 		return (-1);
 	}
-	*raddrs = (struct sockaddr *)&addrs->addr[0];
+	*raddrs = &addrs->addr[0].sa;
 	cnt = 0;
-	sa = (struct sockaddr *)&addrs->addr[0];
+	sa = &addrs->addr[0].sa;
 	lim = (caddr_t)addrs + opt_len;
 	while (((caddr_t)sa < lim) && (sa->sa_len > 0)) {
 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
@@ -436,7 +436,7 @@ sctp_freepaddrs(struct sockaddr *addrs)
 	void *fr_addr;
 
 	/* Take away the hidden association id */
-	fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
+	fr_addr = (void *)((caddr_t)addrs - offsetof(struct sctp_getaddresses, addr));
 	/* Now free it */
 	free(fr_addr);
 }
@@ -466,7 +466,7 @@ sctp_getladdrs(int sd, sctp_assoc_t id, struct sockadd
 		errno = ENOTCONN;
 		return (-1);
 	}
-	opt_len = (socklen_t)(size_of_addresses + sizeof(sctp_assoc_t));
+	opt_len = (socklen_t)(size_of_addresses + sizeof(struct sctp_getaddresses));
 	addrs = calloc(1, (size_t)opt_len);
 	if (addrs == NULL) {
 		errno = ENOMEM;
@@ -480,9 +480,9 @@ sctp_getladdrs(int sd, sctp_assoc_t id, struct sockadd
 		errno = ENOMEM;
 		return (-1);
 	}
-	*raddrs = (struct sockaddr *)&addrs->addr[0];
+	*raddrs = &addrs->addr[0].sa;
 	cnt = 0;
-	sa = (struct sockaddr *)&addrs->addr[0];
+	sa = &addrs->addr[0].sa;
 	lim = (caddr_t)addrs + opt_len;
 	while (((caddr_t)sa < lim) && (sa->sa_len > 0)) {
 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
@@ -497,7 +497,7 @@ sctp_freeladdrs(struct sockaddr *addrs)
 	void *fr_addr;
 
 	/* Take away the hidden association id */
-	fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
+	fr_addr = (void *)((caddr_t)addrs - offsetof(struct sctp_getaddresses, addr));
 	/* Now free it */
 	free(fr_addr);
 }

Modified: stable/12/sys/netinet/sctp_uio.h
==============================================================================
--- stable/12/sys/netinet/sctp_uio.h	Mon Aug 24 08:22:37 2020	(r364619)
+++ stable/12/sys/netinet/sctp_uio.h	Mon Aug 24 08:25:00 2020	(r364620)
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
 #define _NETINET_SCTP_UIO_H_
 
 
-#if ! defined(_KERNEL)
+#if !defined(_KERNEL)
 #include <stdint.h>
 #endif
 #include <sys/types.h>
@@ -633,10 +633,15 @@ struct sctp_setpeerprim {
 	uint8_t sspp_padding[4];
 };
 
+union sctp_sockstore {
+	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
+	struct sockaddr sa;
+};
+
 struct sctp_getaddresses {
 	sctp_assoc_t sget_assoc_id;
-	/* addr is filled in for N * sockaddr_storage */
-	struct sockaddr addr[1];
+	union sctp_sockstore addr[];
 };
 
 struct sctp_status {
@@ -1142,12 +1147,6 @@ struct sctpstat {
 #define SCTP_STAT_DECR_COUNTER32(_x) SCTP_STAT_DECR(_x)
 #define SCTP_STAT_DECR_COUNTER64(_x) SCTP_STAT_DECR(_x)
 #define SCTP_STAT_DECR_GAUGE32(_x) SCTP_STAT_DECR(_x)
-
-union sctp_sockstore {
-	struct sockaddr_in sin;
-	struct sockaddr_in6 sin6;
-	struct sockaddr sa;
-};
 
 
 /***********************************/

Modified: stable/12/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/12/sys/netinet/sctp_usrreq.c	Mon Aug 24 08:22:37 2020	(r364619)
+++ stable/12/sys/netinet/sctp_usrreq.c	Mon Aug 24 08:25:00 2020	(r364620)
@@ -970,7 +970,7 @@ sctp_shutdown(struct socket *so)
  * returns 0 on success, 1 on error
  */
 static uint32_t
-sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa)
+sctp_fill_user_address(union sctp_sockstore *ss, struct sockaddr *sa)
 {
 #ifdef INET6
 	struct sockaddr_in6 lsa6;
@@ -991,7 +991,7 @@ static size_t
 sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
     struct sctp_tcb *stcb,
     size_t limit,
-    struct sockaddr_storage *sas,
+    union sctp_sockstore *addr,
     uint32_t vrf_id)
 {
 	struct sctp_ifn *sctp_ifn;
@@ -1106,18 +1106,18 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 							if (actual + sizeof(struct sockaddr_in6) > limit) {
 								return (actual);
 							}
-							in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas);
-							((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
-							sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6));
+							in6_sin_2_v4mapsin6(sin, &addr->sin6);
+							addr->sin6.sin6_port = inp->sctp_lport;
+							addr = (union sctp_sockstore *)((caddr_t)addr + sizeof(struct sockaddr_in6));
 							actual += sizeof(struct sockaddr_in6);
 						} else {
 #endif
 							if (actual + sizeof(struct sockaddr_in) > limit) {
 								return (actual);
 							}
-							memcpy(sas, sin, sizeof(struct sockaddr_in));
-							((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
-							sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in));
+							memcpy(addr, sin, sizeof(struct sockaddr_in));
+							addr->sin.sin_port = inp->sctp_lport;
+							addr = (union sctp_sockstore *)((caddr_t)addr + sizeof(struct sockaddr_in));
 							actual += sizeof(struct sockaddr_in);
 #ifdef INET6
 						}
@@ -1169,9 +1169,9 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 						if (actual + sizeof(struct sockaddr_in6) > limit) {
 							return (actual);
 						}
-						memcpy(sas, sin6, sizeof(struct sockaddr_in6));
-						((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
-						sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6));
+						memcpy(addr, sin6, sizeof(struct sockaddr_in6));
+						addr->sin6.sin6_port = inp->sctp_lport;
+						addr = (union sctp_sockstore *)((caddr_t)addr + sizeof(struct sockaddr_in6));
 						actual += sizeof(struct sockaddr_in6);
 					} else {
 						continue;
@@ -1198,24 +1198,24 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 			if (actual + sa_len > limit) {
 				return (actual);
 			}
-			if (sctp_fill_user_address(sas, &laddr->ifa->address.sa))
+			if (sctp_fill_user_address(addr, &laddr->ifa->address.sa))
 				continue;
 			switch (laddr->ifa->address.sa.sa_family) {
 #ifdef INET
 			case AF_INET:
-				((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
+				addr->sin.sin_port = inp->sctp_lport;
 				break;
 #endif
 #ifdef INET6
 			case AF_INET6:
-				((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
+				addr->sin6.sin6_port = inp->sctp_lport;
 				break;
 #endif
 			default:
 				/* TSNH */
 				break;
 			}
-			sas = (struct sockaddr_storage *)((caddr_t)sas + sa_len);
+			addr = (union sctp_sockstore *)((caddr_t)addr + sa_len);
 			actual += sa_len;
 		}
 	}
@@ -1226,13 +1226,13 @@ static size_t
 sctp_fill_up_addresses(struct sctp_inpcb *inp,
     struct sctp_tcb *stcb,
     size_t limit,
-    struct sockaddr_storage *sas)
+    union sctp_sockstore *addr)
 {
 	size_t size = 0;
 
 	SCTP_IPI_ADDR_RLOCK();
 	/* fill up addresses for the endpoint's default vrf */
-	size = sctp_fill_up_addresses_vrf(inp, stcb, limit, sas,
+	size = sctp_fill_up_addresses_vrf(inp, stcb, limit, addr,
 	    inp->def_vrf_id);
 	SCTP_IPI_ADDR_RUNLOCK();
 	return (size);
@@ -2207,7 +2207,7 @@ flags_out:
 		 */
 		{
 			size_t cpsz, left;
-			struct sockaddr_storage *sas;
+			union sctp_sockstore *addr;
 			struct sctp_nets *net;
 			struct sctp_getaddresses *saddr;
 
@@ -2215,9 +2215,9 @@ flags_out:
 			SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
 
 			if (stcb) {
-				left = (*optsize) - sizeof(sctp_assoc_t);
-				*optsize = sizeof(sctp_assoc_t);
-				sas = (struct sockaddr_storage *)&saddr->addr[0];
+				left = *optsize - offsetof(struct sctp_getaddresses, addr);
+				*optsize = offsetof(struct sctp_getaddresses, addr);
+				addr = &saddr->addr[0];
 
 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
 					switch (net->ro._l_addr.sa.sa_family) {
@@ -2255,16 +2255,16 @@ flags_out:
 					    (net->ro._l_addr.sa.sa_family == AF_INET)) {
 						/* Must map the address */
 						in6_sin_2_v4mapsin6(&net->ro._l_addr.sin,
-						    (struct sockaddr_in6 *)sas);
+						    &addr->sin6);
 					} else {
-						memcpy(sas, &net->ro._l_addr, cpsz);
+						memcpy(addr, &net->ro._l_addr, cpsz);
 					}
 #else
-					memcpy(sas, &net->ro._l_addr, cpsz);
+					memcpy(addr, &net->ro._l_addr, cpsz);
 #endif
-					((struct sockaddr_in *)sas)->sin_port = stcb->rport;
+					addr->sin.sin_port = stcb->rport;
 
-					sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz);
+					addr = (union sctp_sockstore *)((caddr_t)addr + cpsz);
 					left -= cpsz;
 					*optsize += cpsz;
 				}
@@ -2278,19 +2278,17 @@ flags_out:
 	case SCTP_GET_LOCAL_ADDRESSES:
 		{
 			size_t limit, actual;
-			struct sockaddr_storage *sas;
 			struct sctp_getaddresses *saddr;
 
 			SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize);
 			SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
 
-			sas = (struct sockaddr_storage *)&saddr->addr[0];
-			limit = *optsize - sizeof(sctp_assoc_t);
-			actual = sctp_fill_up_addresses(inp, stcb, limit, sas);
+			limit = *optsize - offsetof(struct sctp_getaddresses, addr);
+			actual = sctp_fill_up_addresses(inp, stcb, limit, saddr->addr);
 			if (stcb) {
 				SCTP_TCB_UNLOCK(stcb);
 			}
-			*optsize = sizeof(sctp_assoc_t) + actual;
+			*optsize = offsetof(struct sctp_getaddresses, addr) + actual;
 			break;
 		}
 	case SCTP_PEER_ADDR_PARAMS:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202008240825.07O8P0F5070954>