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);
}