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:
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to