Module Name: src Committed By: rjs Date: Tue Jul 31 13:36:31 UTC 2018
Modified Files: src/sys/netinet: sctp_uio.h sctp_usrreq.c Log Message: Change implementation of sctp_connectx() to use ioctl(2). To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/netinet/sctp_uio.h cvs rdiff -u -r1.10 -r1.11 src/sys/netinet/sctp_usrreq.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/sctp_uio.h diff -u src/sys/netinet/sctp_uio.h:1.3 src/sys/netinet/sctp_uio.h:1.4 --- src/sys/netinet/sctp_uio.h:1.3 Sun Dec 10 11:52:14 2017 +++ src/sys/netinet/sctp_uio.h Tue Jul 31 13:36:31 2018 @@ -1,5 +1,5 @@ /* $KAME: sctp_uio.h,v 1.11 2005/03/06 16:04:18 itojun Exp $ */ -/* $NetBSD: sctp_uio.h,v 1.3 2017/12/10 11:52:14 rjs Exp $ */ +/* $NetBSD: sctp_uio.h,v 1.4 2018/07/31 13:36:31 rjs Exp $ */ #ifndef __SCTP_UIO_H__ #define __SCTP_UIO_H__ @@ -584,6 +584,14 @@ struct sctp_recvv_rn { #define SCTP_RECVV_NXTINFO 0x0002 #define SCTP_RECVV_RN 0x0003 +struct sctp_connectx_addrs { + int cx_num; + int cx_len; + void *cx_addrs; +} __packed; + +#define SIOCCONNECTX _IOWR('s', 11, struct sctp_connectx_addrs) +#define SIOCCONNECTXDEL _IOWR('s', 12, struct sctp_connectx_addrs) /* * API system calls Index: src/sys/netinet/sctp_usrreq.c diff -u src/sys/netinet/sctp_usrreq.c:1.10 src/sys/netinet/sctp_usrreq.c:1.11 --- src/sys/netinet/sctp_usrreq.c:1.10 Tue May 1 07:21:39 2018 +++ src/sys/netinet/sctp_usrreq.c Tue Jul 31 13:36:31 2018 @@ -1,5 +1,5 @@ /* $KAME: sctp_usrreq.c,v 1.50 2005/06/16 20:45:29 jinmei Exp $ */ -/* $NetBSD: sctp_usrreq.c,v 1.10 2018/05/01 07:21:39 maxv Exp $ */ +/* $NetBSD: sctp_usrreq.c,v 1.11 2018/07/31 13:36:31 rjs Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc. @@ -33,7 +33,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sctp_usrreq.c,v 1.10 2018/05/01 07:21:39 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sctp_usrreq.c,v 1.11 2018/07/31 13:36:31 rjs Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1134,19 +1134,27 @@ sctp_count_max_addresses(struct sctp_inp } static int -sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, struct mbuf *m, - struct lwp *l, int delay) +sctp_do_connect_x(struct socket *so, struct sctp_connectx_addrs *sca, + struct lwp *l, int delay) { int error = 0; + struct sctp_inpcb *inp; struct sctp_tcb *stcb = NULL; struct sockaddr *sa; - int num_v6=0, num_v4=0, *totaddrp, totaddr, i, incr, at; + int num_v6=0, num_v4=0, totaddr, i, incr, at; + char buf[2048]; + size_t len; + sctp_assoc_t id; #ifdef SCTP_DEBUG if (sctp_debug_on & SCTP_DEBUG_PCB1) { printf("Connectx called\n"); } #endif /* SCTP_DEBUG */ + inp = (struct sctp_inpcb *)so->so_pcb; + if (inp == 0) + return EINVAL; + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { /* We are already connected AND the TCP model */ @@ -1168,9 +1176,16 @@ sctp_do_connect_x(struct socket *so, str return (EFAULT); } - totaddrp = mtod(m, int *); - totaddr = *totaddrp; - sa = (struct sockaddr *)(totaddrp + 1); + len = sca->cx_len; + totaddr = sca->cx_num; + if (len > sizeof(buf)) { + return E2BIG; + } + error = copyin(sca->cx_addrs, buf, len); + if (error) { + return error; + } + sa = (struct sockaddr *)buf; at = incr = 0; /* account and validate addresses */ SCTP_INP_WLOCK(inp); @@ -1201,13 +1216,13 @@ sctp_do_connect_x(struct socket *so, str SCTP_TCB_UNLOCK(stcb); return (EALREADY); } - if ((at + incr) > m->m_len) { + if ((at + incr) > len) { totaddr = i; break; } sa = (struct sockaddr *)((vaddr_t)sa + incr); } - sa = (struct sockaddr *)(totaddrp + 1); + sa = (struct sockaddr *)buf; SCTP_INP_WLOCK(inp); SCTP_INP_DECR_REF(inp); SCTP_INP_WUNLOCK(inp); @@ -1252,6 +1267,7 @@ sctp_do_connect_x(struct socket *so, str SCTP_ASOC_CREATE_UNLOCK(inp); return (error); } + /* move to second address */ if (sa->sa_family == AF_INET) sa = (struct sockaddr *)((vaddr_t)sa + sizeof(struct sockaddr_in)); @@ -1280,6 +1296,10 @@ sctp_do_connect_x(struct socket *so, str sa = (struct sockaddr *)((vaddr_t)sa + incr); } stcb->asoc.state = SCTP_STATE_COOKIE_WAIT; + + id = sctp_get_associd(stcb); + memcpy(&sca->cx_num, &id, sizeof(sctp_assoc_t)); + if (delay) { /* doing delayed connection */ stcb->asoc.delayed_connection = 1; @@ -1922,7 +1942,7 @@ sctp_optsget(struct socket *so, struct s break; } } - if ( (stcb == NULL) && + if ((stcb == NULL) && ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) || (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) { /* Lookup via address */ @@ -2099,6 +2119,7 @@ sctp_optsget(struct socket *so, struct s stcb = sctp_findassociation_ep_asocid(inp, sstat->sstat_assoc_id); if (stcb == NULL) { + printf("SCTP status, no stcb\n"); error = EINVAL; break; } @@ -2538,22 +2559,6 @@ sctp_optsset(struct socket *so, struct s memset(sctp_pegs, 0, sizeof(sctp_pegs)); error = 0; break; - case SCTP_CONNECT_X: - if (sopt->sopt_size < (sizeof(int) + sizeof(struct sockaddr_in))) { - error = EINVAL; - break; - } - error = sctp_do_connect_x(so, inp, sopt->sopt_data, curlwp, 0); - break; - - case SCTP_CONNECT_X_DELAYED: - if (sopt->sopt_size < (sizeof(int) + sizeof(struct sockaddr_in))) { - error = EINVAL; - break; - } - error = sctp_do_connect_x(so, inp, sopt->sopt_data, curlwp, 1); - break; - case SCTP_CONNECT_X_COMPLETE: { struct sockaddr *sa; @@ -3829,20 +3834,30 @@ sctp_ioctl(struct socket *so, u_long cmd int error = 0; int family; - family = so->so_proto->pr_domain->dom_family; - switch (family) { + if (cmd == SIOCCONNECTX) { + solock(so); + error = sctp_do_connect_x(so, nam, curlwp, 0); + sounlock(so); + } else if (cmd == SIOCCONNECTXDEL) { + solock(so); + error = sctp_do_connect_x(so, nam, curlwp, 1); + sounlock(so); + } else { + family = so->so_proto->pr_domain->dom_family; + switch (family) { #ifdef INET - case PF_INET: - error = in_control(so, cmd, nam, ifp); - break; + case PF_INET: + error = in_control(so, cmd, nam, ifp); + break; #endif #ifdef INET6 - case PF_INET6: - error = in6_control(so, cmd, nam, ifp); - break; + case PF_INET6: + error = in6_control(so, cmd, nam, ifp); + break; #endif - default: - error = EAFNOSUPPORT; + default: + error = EAFNOSUPPORT; + } } return (error); }