Home | History | Annotate | Download | only in usrsctplib
      1 /*-
      2  * Copyright (c) 1982, 1986, 1988, 1990, 1993
      3  *      The Regents of the University of California.
      4  * Copyright (c) 2004 The FreeBSD Foundation
      5  * Copyright (c) 2004-2008 Robert N. M. Watson
      6  * Copyright (c) 2009-2010 Brad Penoff
      7  * Copyright (c) 2009-2010 Humaira Kamal
      8  * Copyright (c) 2011-2012 Irene Ruengeler
      9  * Copyright (c) 2011-2012 Michael Tuexen
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  *
     33  */
     34 
     35 #include <netinet/sctp_os.h>
     36 #include <netinet/sctp_pcb.h>
     37 #include <netinet/sctputil.h>
     38 #include <netinet/sctp_var.h>
     39 #include <netinet/sctp_sysctl.h>
     40 #include <netinet/sctp_input.h>
     41 #include <netinet/sctp_peeloff.h>
     42 #ifdef INET6
     43 #include <netinet6/sctp6_var.h>
     44 #endif
     45 #if defined(__Userspace_os_Linux)
     46 #define __FAVOR_BSD    /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
     47 #endif
     48 #if !defined (__Userspace_os_Windows)
     49 #if defined INET || defined INET6
     50 #include <netinet/udp.h>
     51 #endif
     52 #include <arpa/inet.h>
     53 #else
     54 #include <user_socketvar.h>
     55 #endif
     56 userland_mutex_t accept_mtx;
     57 userland_cond_t accept_cond;
     58 #ifdef _WIN32
     59 #include <time.h>
     60 #include <sys/timeb.h>
     61 #endif
     62 
     63 MALLOC_DEFINE(M_PCB, "sctp_pcb", "sctp pcb");
     64 MALLOC_DEFINE(M_SONAME, "sctp_soname", "sctp soname");
     65 #define MAXLEN_MBUF_CHAIN  32
     66 
     67 /* Prototypes */
     68 extern int sctp_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
     69                        struct mbuf *top, struct mbuf *control, int flags,
     70                      /* proc is a dummy in __Userspace__ and will not be passed to sctp_lower_sosend */                       struct proc *p);
     71 
     72 extern int sctp_attach(struct socket *so, int proto, uint32_t vrf_id);
     73 extern int sctpconn_attach(struct socket *so, int proto, uint32_t vrf_id);
     74 
     75 void
     76 usrsctp_init(uint16_t port,
     77              int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
     78              void (*debug_printf)(const char *format, ...))
     79 {
     80 	sctp_init(port, conn_output, debug_printf);
     81 }
     82 
     83 
     84 /* Taken from  usr/src/sys/kern/uipc_sockbuf.c and modified for __Userspace__*/
     85 /*
     86  * Socantsendmore indicates that no more data will be sent on the socket; it
     87  * would normally be applied to a socket when the user informs the system
     88  * that no more data is to be sent, by the protocol code (in case
     89  * PRU_SHUTDOWN).  Socantrcvmore indicates that no more data will be
     90  * received, and will normally be applied to the socket by a protocol when it
     91  * detects that the peer will send no more data.  Data queued for reading in
     92  * the socket may yet be read.
     93  */
     94 
     95 void socantrcvmore_locked(struct socket *so)
     96 {
     97 	SOCKBUF_LOCK_ASSERT(&so->so_rcv);
     98 	so->so_rcv.sb_state |= SBS_CANTRCVMORE;
     99 	sorwakeup_locked(so);
    100 }
    101 
    102 void socantrcvmore(struct socket *so)
    103 {
    104 	SOCKBUF_LOCK(&so->so_rcv);
    105 	socantrcvmore_locked(so);
    106 }
    107 
    108 void
    109 socantsendmore_locked(struct socket *so)
    110 {
    111 	SOCKBUF_LOCK_ASSERT(&so->so_snd);
    112 	so->so_snd.sb_state |= SBS_CANTSENDMORE;
    113 	sowwakeup_locked(so);
    114 }
    115 
    116 void
    117 socantsendmore(struct socket *so)
    118 {
    119 	SOCKBUF_LOCK(&so->so_snd);
    120 	socantsendmore_locked(so);
    121 }
    122 
    123 
    124 
    125 /* Taken from  usr/src/sys/kern/uipc_sockbuf.c and called within sctp_lower_sosend.
    126  */
    127 int
    128 sbwait(struct sockbuf *sb)
    129 {
    130 #if defined(__Userspace__) /* __Userspace__ */
    131 
    132 	SOCKBUF_LOCK_ASSERT(sb);
    133 
    134 	sb->sb_flags |= SB_WAIT;
    135 #if defined (__Userspace_os_Windows)
    136 	if (SleepConditionVariableCS(&(sb->sb_cond), &(sb->sb_mtx), INFINITE))
    137 		return 0;
    138 	else
    139 		return -1;
    140 #else
    141 	return (pthread_cond_wait(&(sb->sb_cond), &(sb->sb_mtx)));
    142 #endif
    143 
    144 #else
    145 	SOCKBUF_LOCK_ASSERT(sb);
    146 
    147 	sb->sb_flags |= SB_WAIT;
    148 	return (msleep(&sb->sb_cc, &sb->sb_mtx,
    149 	    (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "sbwait",
    150 	    sb->sb_timeo));
    151 #endif
    152 }
    153 
    154 
    155 
    156 
    157 /* Taken from  /src/sys/kern/uipc_socket.c
    158  * and modified for __Userspace__
    159  */
    160 static struct socket *
    161 soalloc(void)
    162 {
    163 	struct socket *so;
    164 
    165 	/*
    166 	 * soalloc() sets of socket layer state for a socket,
    167 	 * called only by socreate() and sonewconn().
    168 	 *
    169 	 * sodealloc() tears down socket layer state for a socket,
    170 	 * called only by sofree() and sonewconn().
    171 	 * __Userspace__ TODO : Make sure so is properly deallocated
    172 	 * when tearing down the connection.
    173 	 */
    174 
    175 	so = (struct socket *)malloc(sizeof(struct socket));
    176 
    177 	if (so == NULL) {
    178 		return (NULL);
    179 	}
    180 	memset(so, 0, sizeof(struct socket));
    181 
    182 	/* __Userspace__ Initializing the socket locks here */
    183 	SOCKBUF_LOCK_INIT(&so->so_snd, "so_snd");
    184 	SOCKBUF_LOCK_INIT(&so->so_rcv, "so_rcv");
    185 	SOCKBUF_COND_INIT(&so->so_snd);
    186 	SOCKBUF_COND_INIT(&so->so_rcv);
    187 	SOCK_COND_INIT(so); /* timeo_cond */
    188 
    189 	/* __Userspace__ Any ref counting required here? Will we have any use for aiojobq?
    190 	   What about gencnt and numopensockets?*/
    191 	TAILQ_INIT(&so->so_aiojobq);
    192 	return (so);
    193 }
    194 
    195 static void
    196 sodealloc(struct socket *so)
    197 {
    198 
    199 	KASSERT(so->so_count == 0, ("sodealloc(): so_count %d", so->so_count));
    200 	KASSERT(so->so_pcb == NULL, ("sodealloc(): so_pcb != NULL"));
    201 
    202 	SOCKBUF_COND_DESTROY(&so->so_snd);
    203 	SOCKBUF_COND_DESTROY(&so->so_rcv);
    204 
    205 	SOCK_COND_DESTROY(so);
    206 
    207 	SOCKBUF_LOCK_DESTROY(&so->so_snd);
    208 	SOCKBUF_LOCK_DESTROY(&so->so_rcv);
    209 
    210 	free(so);
    211 }
    212 
    213 /* Taken from  /src/sys/kern/uipc_socket.c
    214  * and modified for __Userspace__
    215  */
    216 void
    217 sofree(struct socket *so)
    218 {
    219 	struct socket *head;
    220 
    221 	ACCEPT_LOCK_ASSERT();
    222 	SOCK_LOCK_ASSERT(so);
    223 	/* SS_NOFDREF unset in accept call.  this condition seems irrelevent
    224 	 *  for __Userspace__...
    225 	 */
    226 	if (so->so_count != 0 ||
    227 	    (so->so_state & SS_PROTOREF) || (so->so_qstate & SQ_COMP)) {
    228 		SOCK_UNLOCK(so);
    229 		ACCEPT_UNLOCK();
    230 		return;
    231 	}
    232 	head = so->so_head;
    233 	if (head != NULL) {
    234 		KASSERT((so->so_qstate & SQ_COMP) != 0 ||
    235 		    (so->so_qstate & SQ_INCOMP) != 0,
    236 		    ("sofree: so_head != NULL, but neither SQ_COMP nor "
    237 		    "SQ_INCOMP"));
    238 		KASSERT((so->so_qstate & SQ_COMP) == 0 ||
    239 		    (so->so_qstate & SQ_INCOMP) == 0,
    240 		    ("sofree: so->so_qstate is SQ_COMP and also SQ_INCOMP"));
    241 		TAILQ_REMOVE(&head->so_incomp, so, so_list);
    242 		head->so_incqlen--;
    243 		so->so_qstate &= ~SQ_INCOMP;
    244 		so->so_head = NULL;
    245 	}
    246 	KASSERT((so->so_qstate & SQ_COMP) == 0 &&
    247 	    (so->so_qstate & SQ_INCOMP) == 0,
    248 	    ("sofree: so_head == NULL, but still SQ_COMP(%d) or SQ_INCOMP(%d)",
    249 	    so->so_qstate & SQ_COMP, so->so_qstate & SQ_INCOMP));
    250 	if (so->so_options & SCTP_SO_ACCEPTCONN) {
    251 		KASSERT((TAILQ_EMPTY(&so->so_comp)), ("sofree: so_comp populated"));
    252 		KASSERT((TAILQ_EMPTY(&so->so_incomp)), ("sofree: so_comp populated"));
    253 	}
    254 	SOCK_UNLOCK(so);
    255 	ACCEPT_UNLOCK();
    256 	sctp_close(so); /* was...    sctp_detach(so); */
    257 	/*
    258 	 * From this point on, we assume that no other references to this
    259 	 * socket exist anywhere else in the stack.  Therefore, no locks need
    260 	 * to be acquired or held.
    261 	 *
    262 	 * We used to do a lot of socket buffer and socket locking here, as
    263 	 * well as invoke sorflush() and perform wakeups.  The direct call to
    264 	 * dom_dispose() and sbrelease_internal() are an inlining of what was
    265 	 * necessary from sorflush().
    266 	 *
    267 	 * Notice that the socket buffer and kqueue state are torn down
    268 	 * before calling pru_detach.  This means that protocols shold not
    269 	 * assume they can perform socket wakeups, etc, in their detach code.
    270 	 */
    271 	sodealloc(so);
    272 }
    273 
    274 
    275 
    276 /* Taken from  /src/sys/kern/uipc_socket.c */
    277 int
    278 soabort(so)
    279 	struct socket *so;
    280 {
    281 	int error;
    282 #if defined(INET6)
    283 	struct sctp_inpcb *inp;
    284 #endif
    285 
    286 #if defined(INET6)
    287 	inp = (struct sctp_inpcb *)so->so_pcb;
    288 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    289 		error = sctp6_abort(so);
    290 	} else {
    291 #if defined(INET)
    292 		error = sctp_abort(so);
    293 #else
    294 		error = EAFNOSUPPORT;
    295 #endif
    296 	}
    297 #elif defined(INET)
    298 	error = sctp_abort(so);
    299 #else
    300 	error = EAFNOSUPPORT;
    301 #endif
    302 	if (error) {
    303 		sofree(so);
    304 		return error;
    305 	}
    306 	return (0);
    307 }
    308 
    309 
    310 /* Taken from  usr/src/sys/kern/uipc_socket.c and called within sctp_connect (sctp_usrreq.c).
    311  *  We use sctp_connect for send_one_init_real in ms1.
    312  */
    313 void
    314 soisconnecting(struct socket *so)
    315 {
    316 
    317 	SOCK_LOCK(so);
    318 	so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
    319 	so->so_state |= SS_ISCONNECTING;
    320 	SOCK_UNLOCK(so);
    321 }
    322 
    323 /* Taken from  usr/src/sys/kern/uipc_socket.c and called within sctp_disconnect (sctp_usrreq.c).
    324  *  TODO Do we use sctp_disconnect?
    325  */
    326 void
    327 soisdisconnecting(struct socket *so)
    328 {
    329 
    330         /*
    331          * Note: This code assumes that SOCK_LOCK(so) and
    332          * SOCKBUF_LOCK(&so->so_rcv) are the same.
    333          */
    334         SOCKBUF_LOCK(&so->so_rcv);
    335         so->so_state &= ~SS_ISCONNECTING;
    336         so->so_state |= SS_ISDISCONNECTING;
    337         so->so_rcv.sb_state |= SBS_CANTRCVMORE;
    338         sorwakeup_locked(so);
    339         SOCKBUF_LOCK(&so->so_snd);
    340         so->so_snd.sb_state |= SBS_CANTSENDMORE;
    341         sowwakeup_locked(so);
    342         wakeup("dummy",so);
    343         /* requires 2 args but this was in orig */
    344         /* wakeup(&so->so_timeo); */
    345 }
    346 
    347 
    348 /* Taken from sys/kern/kern_synch.c and
    349    modified for __Userspace__
    350 */
    351 
    352 /*
    353  * Make all threads sleeping on the specified identifier runnable.
    354  * Associating wakeup with so_timeo identifier and timeo_cond
    355  * condition variable. TODO. If we use iterator thread then we need to
    356  * modify wakeup so it can distinguish between iterator identifier and
    357  * timeo identifier.
    358  */
    359 void
    360 wakeup(ident, so)
    361 	void *ident;
    362 	struct socket *so;
    363 {
    364 	SOCK_LOCK(so);
    365 #if defined (__Userspace_os_Windows)
    366 	WakeAllConditionVariable(&(so)->timeo_cond);
    367 #else
    368 	pthread_cond_broadcast(&(so)->timeo_cond);
    369 #endif
    370 	SOCK_UNLOCK(so);
    371 }
    372 
    373 
    374 /*
    375  * Make a thread sleeping on the specified identifier runnable.
    376  * May wake more than one thread if a target thread is currently
    377  * swapped out.
    378  */
    379 void
    380 wakeup_one(ident)
    381 	void *ident;
    382 {
    383 	/* __Userspace__ Check: We are using accept_cond for wakeup_one.
    384 	  It seems that wakeup_one is only called within
    385 	  soisconnected() and sonewconn() with ident &head->so_timeo
    386 	  head is so->so_head, which is back pointer to listen socket
    387 	  This seems to indicate that the use of accept_cond is correct
    388 	  since socket where accepts occur is so_head in all
    389 	  subsidiary sockets.
    390 	 */
    391 	ACCEPT_LOCK();
    392 #if defined (__Userspace_os_Windows)
    393 	WakeAllConditionVariable(&accept_cond);
    394 #else
    395 	pthread_cond_broadcast(&accept_cond);
    396 #endif
    397 	ACCEPT_UNLOCK();
    398 }
    399 
    400 
    401 /* Called within sctp_process_cookie_[existing/new] */
    402 void
    403 soisconnected(struct socket *so)
    404 {
    405 	struct socket *head;
    406 
    407 	ACCEPT_LOCK();
    408 	SOCK_LOCK(so);
    409 	so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
    410 	so->so_state |= SS_ISCONNECTED;
    411 	head = so->so_head;
    412 	if (head != NULL && (so->so_qstate & SQ_INCOMP)) {
    413 		SOCK_UNLOCK(so);
    414 		TAILQ_REMOVE(&head->so_incomp, so, so_list);
    415 		head->so_incqlen--;
    416 		so->so_qstate &= ~SQ_INCOMP;
    417 		TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
    418 		head->so_qlen++;
    419 		so->so_qstate |= SQ_COMP;
    420 		ACCEPT_UNLOCK();
    421 		sorwakeup(head);
    422 		wakeup_one(&head->so_timeo);
    423 		return;
    424 	}
    425 	SOCK_UNLOCK(so);
    426 	ACCEPT_UNLOCK();
    427 	wakeup(&so->so_timeo, so);
    428 	sorwakeup(so);
    429 	sowwakeup(so);
    430 
    431 }
    432 
    433 /* called within sctp_handle_cookie_echo */
    434 
    435 struct socket *
    436 sonewconn(struct socket *head, int connstatus)
    437 {
    438 	struct socket *so;
    439 	int over;
    440 
    441 	ACCEPT_LOCK();
    442 	over = (head->so_qlen > 3 * head->so_qlimit / 2);
    443 	ACCEPT_UNLOCK();
    444 #ifdef REGRESSION
    445 	if (regression_sonewconn_earlytest && over)
    446 #else
    447 	if (over)
    448 #endif
    449 		return (NULL);
    450 	so = soalloc();
    451 	if (so == NULL)
    452 		return (NULL);
    453 	so->so_head = head;
    454 	so->so_type = head->so_type;
    455 	so->so_options = head->so_options &~ SCTP_SO_ACCEPTCONN;
    456 	so->so_linger = head->so_linger;
    457 	so->so_state = head->so_state | SS_NOFDREF;
    458 	so->so_dom = head->so_dom;
    459 #ifdef MAC
    460 	SOCK_LOCK(head);
    461 	mac_create_socket_from_socket(head, so);
    462 	SOCK_UNLOCK(head);
    463 #endif
    464 	if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat)) {
    465 		sodealloc(so);
    466 		return (NULL);
    467 	}
    468 	switch (head->so_dom) {
    469 #ifdef INET
    470 	case AF_INET:
    471 		if (sctp_attach(so, IPPROTO_SCTP, SCTP_DEFAULT_VRFID)) {
    472 			sodealloc(so);
    473 			return (NULL);
    474 		}
    475 		break;
    476 #endif
    477 #ifdef INET6
    478 	case AF_INET6:
    479 		if (sctp6_attach(so, IPPROTO_SCTP, SCTP_DEFAULT_VRFID)) {
    480 			sodealloc(so);
    481 			return (NULL);
    482 		}
    483 		break;
    484 #endif
    485 	case AF_CONN:
    486 		if (sctpconn_attach(so, IPPROTO_SCTP, SCTP_DEFAULT_VRFID)) {
    487 			sodealloc(so);
    488 			return (NULL);
    489 		}
    490 		break;
    491 	default:
    492 		sodealloc(so);
    493 		return (NULL);
    494 		break;
    495 	}
    496 	so->so_rcv.sb_lowat = head->so_rcv.sb_lowat;
    497 	so->so_snd.sb_lowat = head->so_snd.sb_lowat;
    498 	so->so_rcv.sb_timeo = head->so_rcv.sb_timeo;
    499 	so->so_snd.sb_timeo = head->so_snd.sb_timeo;
    500 	so->so_rcv.sb_flags |= head->so_rcv.sb_flags & SB_AUTOSIZE;
    501 	so->so_snd.sb_flags |= head->so_snd.sb_flags & SB_AUTOSIZE;
    502 	so->so_state |= connstatus;
    503 	ACCEPT_LOCK();
    504 	if (connstatus) {
    505 		TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
    506 		so->so_qstate |= SQ_COMP;
    507 		head->so_qlen++;
    508 	} else {
    509 		/*
    510 		 * Keep removing sockets from the head until there's room for
    511 		 * us to insert on the tail.  In pre-locking revisions, this
    512 		 * was a simple if(), but as we could be racing with other
    513 		 * threads and soabort() requires dropping locks, we must
    514 		 * loop waiting for the condition to be true.
    515 		 */
    516 		while (head->so_incqlen > head->so_qlimit) {
    517 			struct socket *sp;
    518 			sp = TAILQ_FIRST(&head->so_incomp);
    519 			TAILQ_REMOVE(&head->so_incomp, sp, so_list);
    520 			head->so_incqlen--;
    521 			sp->so_qstate &= ~SQ_INCOMP;
    522 			sp->so_head = NULL;
    523 			ACCEPT_UNLOCK();
    524 			soabort(sp);
    525 			ACCEPT_LOCK();
    526 		}
    527 		TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
    528 		so->so_qstate |= SQ_INCOMP;
    529 		head->so_incqlen++;
    530 	}
    531 	ACCEPT_UNLOCK();
    532 	if (connstatus) {
    533 		sorwakeup(head);
    534 		wakeup_one(&head->so_timeo);
    535 	}
    536 	return (so);
    537 
    538 }
    539 
    540 /* From /src/sys/sys/sysproto.h */
    541 struct sctp_generic_sendmsg_args {
    542 	int sd;
    543 	caddr_t msg;
    544 	int mlen;
    545 	caddr_t to;
    546 	socklen_t tolen;  /* was __socklen_t */
    547 	struct sctp_sndrcvinfo * sinfo;
    548 	int flags;
    549 };
    550 
    551 struct sctp_generic_recvmsg_args {
    552         int sd;
    553         struct iovec *iov;
    554         int iovlen;
    555         struct sockaddr *from;
    556         socklen_t *fromlenaddr; /* was __socklen_t */
    557         struct sctp_sndrcvinfo *sinfo;
    558         int *msg_flags;
    559 };
    560 
    561 
    562  /*
    563    Source: /src/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
    564  */
    565 static __inline__ int
    566 copy_to_user(void *dst, void *src, int len) {
    567 	memcpy(dst, src, len);
    568 	return 0;
    569 }
    570 
    571 static __inline__ int
    572 copy_from_user(void *dst, void *src, int len) {
    573 	memcpy(dst, src, len);
    574 	return 0;
    575 }
    576 
    577 /*
    578  References:
    579  src/sys/dev/lmc/if_lmc.h:
    580  src/sys/powerpc/powerpc/copyinout.c
    581  src/sys/sys/systm.h
    582 */
    583 # define copyin(u, k, len)	copy_from_user(k, u, len)
    584 
    585 /* References:
    586    src/sys/powerpc/powerpc/copyinout.c
    587    src/sys/sys/systm.h
    588 */
    589 # define copyout(k, u, len)	copy_to_user(u, k, len)
    590 
    591 
    592 /* copyiniov definition copied/modified from src/sys/kern/kern_subr.c */
    593 int
    594 copyiniov(struct iovec *iovp, u_int iovcnt, struct iovec **iov, int error)
    595 {
    596 	u_int iovlen;
    597 
    598 	*iov = NULL;
    599 	if (iovcnt > UIO_MAXIOV)
    600 		return (error);
    601 	iovlen = iovcnt * sizeof (struct iovec);
    602 	*iov = malloc(iovlen); /*, M_IOV, M_WAITOK); */
    603 	error = copyin(iovp, *iov, iovlen);
    604 	if (error) {
    605 		free(*iov); /*, M_IOV); */
    606 		*iov = NULL;
    607 	}
    608 	return (error);
    609 }
    610 
    611 /* (__Userspace__) version of uiomove */
    612 int
    613 uiomove(void *cp, int n, struct uio *uio)
    614 {
    615 	struct iovec *iov;
    616 	int cnt;
    617 	int error = 0;
    618 
    619 	if ((uio->uio_rw != UIO_READ) &&
    620 	    (uio->uio_rw != UIO_WRITE)) {
    621 		return (EINVAL);
    622 	}
    623 
    624 	while (n > 0 && uio->uio_resid) {
    625 		iov = uio->uio_iov;
    626 		cnt = iov->iov_len;
    627 		if (cnt == 0) {
    628 			uio->uio_iov++;
    629 			uio->uio_iovcnt--;
    630 			continue;
    631 		}
    632 		if (cnt > n)
    633 			cnt = n;
    634 
    635 		switch (uio->uio_segflg) {
    636 
    637 		case UIO_USERSPACE:
    638 			if (uio->uio_rw == UIO_READ)
    639 				error = copyout(cp, iov->iov_base, cnt);
    640 			else
    641 				error = copyin(iov->iov_base, cp, cnt);
    642 			if (error)
    643 				goto out;
    644 			break;
    645 
    646 		case UIO_SYSSPACE:
    647 			if (uio->uio_rw == UIO_READ)
    648 				bcopy(cp, iov->iov_base, cnt);
    649 			else
    650 				bcopy(iov->iov_base, cp, cnt);
    651 			break;
    652 		}
    653 		iov->iov_base = (char *)iov->iov_base + cnt;
    654 		iov->iov_len -= cnt;
    655 		uio->uio_resid -= cnt;
    656 		uio->uio_offset += cnt;
    657 		cp = (char *)cp + cnt;
    658 		n -= cnt;
    659 	}
    660 out:
    661 	return (error);
    662 }
    663 
    664 
    665 /* Source: src/sys/kern/uipc_syscalls.c */
    666 int
    667 getsockaddr(namp, uaddr, len)
    668 	struct sockaddr **namp;
    669 	caddr_t uaddr;
    670 	size_t len;
    671 {
    672 	struct sockaddr *sa;
    673 	int error;
    674 
    675 	if (len > SOCK_MAXADDRLEN)
    676 		return (ENAMETOOLONG);
    677 	if (len < offsetof(struct sockaddr, sa_data))
    678 		return (EINVAL);
    679 	MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK);
    680 	error = copyin(uaddr, sa, len);
    681 	if (error) {
    682 		FREE(sa, M_SONAME);
    683 	} else {
    684 #ifdef HAVE_SA_LEN
    685 		sa->sa_len = len;
    686 #endif
    687 		*namp = sa;
    688 	}
    689 	return (error);
    690 }
    691 
    692 
    693 /* Taken from  /src/lib/libc/net/sctp_sys_calls.c
    694  * and modified for __Userspace__
    695  * calling sctp_generic_sendmsg from this function
    696  */
    697 ssize_t
    698 userspace_sctp_sendmsg(struct socket *so,
    699                        const void *data,
    700                        size_t len,
    701                        struct sockaddr *to,
    702                        socklen_t tolen,
    703                        u_int32_t ppid,
    704                        u_int32_t flags,
    705                        u_int16_t stream_no,
    706                        u_int32_t timetolive,
    707                        u_int32_t context)
    708 {
    709 	struct sctp_sndrcvinfo sndrcvinfo, *sinfo = &sndrcvinfo;
    710 	struct uio auio;
    711 	struct iovec iov[1];
    712 
    713 	memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
    714 	sinfo->sinfo_ppid = ppid;
    715 	sinfo->sinfo_flags = flags;
    716 	sinfo->sinfo_stream = stream_no;
    717 	sinfo->sinfo_timetolive = timetolive;
    718 	sinfo->sinfo_context = context;
    719 	sinfo->sinfo_assoc_id = 0;
    720 
    721 
    722 	/* Perform error checks on destination (to) */
    723 	if (tolen > SOCK_MAXADDRLEN){
    724 		errno = ENAMETOOLONG;
    725 		return (-1);
    726 	}
    727 	if ((tolen > 0) &&
    728 	    ((to == NULL) || (tolen < (socklen_t)sizeof(struct sockaddr)))) {
    729 		errno = EINVAL;
    730 		return (-1);
    731 	}
    732 	/* Adding the following as part of defensive programming, in case the application
    733 	   does not do it when preparing the destination address.*/
    734 #ifdef HAVE_SA_LEN
    735 	if (to != NULL) {
    736 		to->sa_len = tolen;
    737 	}
    738 #endif
    739 
    740 	iov[0].iov_base = (caddr_t)data;
    741 	iov[0].iov_len = len;
    742 
    743 	auio.uio_iov =  iov;
    744 	auio.uio_iovcnt = 1;
    745 	auio.uio_segflg = UIO_USERSPACE;
    746 	auio.uio_rw = UIO_WRITE;
    747 	auio.uio_offset = 0;			/* XXX */
    748 	auio.uio_resid = len;
    749 	errno = sctp_lower_sosend(so, to, &auio, NULL, NULL, 0, sinfo);
    750 	if (errno == 0) {
    751 		return (len - auio.uio_resid);
    752 	} else {
    753 		return (-1);
    754 	}
    755 }
    756 
    757 
    758 ssize_t
    759 usrsctp_sendv(struct socket *so,
    760               const void *data,
    761               size_t len,
    762               struct sockaddr *to,
    763               int addrcnt,
    764               void *info,
    765               socklen_t infolen,
    766               unsigned int infotype,
    767               int flags)
    768 {
    769 	struct sctp_sndrcvinfo sinfo;
    770 	struct uio auio;
    771 	struct iovec iov[1];
    772 	int use_sinfo;
    773 
    774 	if (so == NULL) {
    775 		errno = EBADF;
    776 		return (-1);
    777 	}
    778 	memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
    779 	use_sinfo = 0;
    780 	switch (infotype) {
    781 	case SCTP_SENDV_NOINFO:
    782 		if ((infolen != 0) || (info != NULL)) {
    783 			errno = EINVAL;
    784 			return (-1);
    785 		}
    786 		break;
    787 	case SCTP_SENDV_SNDINFO:
    788 		if ((info == NULL) || (infolen != sizeof(struct sctp_sndinfo))) {
    789 			errno = EINVAL;
    790 			return (-1);
    791 		}
    792 		sinfo.sinfo_stream = ((struct sctp_sndinfo *)info)->snd_sid;
    793 		sinfo.sinfo_flags = ((struct sctp_sndinfo *)info)->snd_flags;
    794 		sinfo.sinfo_ppid = ((struct sctp_sndinfo *)info)->snd_ppid;
    795 		sinfo.sinfo_context = ((struct sctp_sndinfo *)info)->snd_context;
    796 		sinfo.sinfo_assoc_id = ((struct sctp_sndinfo *)info)->snd_assoc_id;
    797 		use_sinfo = 1;
    798 		break;
    799 	case SCTP_SENDV_PRINFO:
    800 		if ((info == NULL) || (infolen != sizeof(struct sctp_prinfo))) {
    801 			errno = EINVAL;
    802 			return (-1);
    803 		}
    804 		sinfo.sinfo_stream = 0;
    805 		sinfo.sinfo_flags = PR_SCTP_POLICY(((struct sctp_prinfo *)info)->pr_policy);
    806 		sinfo.sinfo_timetolive = ((struct sctp_prinfo *)info)->pr_value;
    807 		use_sinfo = 1;
    808 		break;
    809 	case SCTP_SENDV_AUTHINFO:
    810 		errno = EINVAL;
    811 		return (-1);
    812 	case SCTP_SENDV_SPA:
    813 		if ((info == NULL) || (infolen != sizeof(struct sctp_sendv_spa))) {
    814 			errno = EINVAL;
    815 			return (-1);
    816 		}
    817 		if (((struct sctp_sendv_spa *)info)->sendv_flags & SCTP_SEND_SNDINFO_VALID) {
    818 			sinfo.sinfo_stream = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_sid;
    819 			sinfo.sinfo_flags = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_flags;
    820 			sinfo.sinfo_ppid = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_ppid;
    821 			sinfo.sinfo_context = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_context;
    822 			sinfo.sinfo_assoc_id = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_assoc_id;
    823 		} else {
    824 			sinfo.sinfo_flags = 0;
    825 			sinfo.sinfo_stream = 0;
    826 		}
    827 		if (((struct sctp_sendv_spa *)info)->sendv_flags & SCTP_SEND_PRINFO_VALID) {
    828 			sinfo.sinfo_flags |= PR_SCTP_POLICY(((struct sctp_sendv_spa *)info)->sendv_prinfo.pr_policy);
    829 			sinfo.sinfo_timetolive = ((struct sctp_sendv_spa *)info)->sendv_prinfo.pr_value;
    830 		}
    831 		if (((struct sctp_sendv_spa *)info)->sendv_flags & SCTP_SEND_AUTHINFO_VALID) {
    832 			errno = EINVAL;
    833 			return (-1);
    834 		}
    835 		use_sinfo = 1;
    836 		break;
    837 	default:
    838 		errno = EINVAL;
    839 		return (-1);
    840 	}
    841 
    842 	/* Perform error checks on destination (to) */
    843 	if (addrcnt > 1) {
    844 		errno = EINVAL;
    845 		return (-1);
    846 	}
    847 
    848 	iov[0].iov_base = (caddr_t)data;
    849 	iov[0].iov_len = len;
    850 
    851 	auio.uio_iov =  iov;
    852 	auio.uio_iovcnt = 1;
    853 	auio.uio_segflg = UIO_USERSPACE;
    854 	auio.uio_rw = UIO_WRITE;
    855 	auio.uio_offset = 0;			/* XXX */
    856 	auio.uio_resid = len;
    857 	errno = sctp_lower_sosend(so, to, &auio, NULL, NULL, flags, use_sinfo ? &sinfo : NULL);
    858 	if (errno == 0) {
    859 		return (len - auio.uio_resid);
    860 	} else {
    861 		return (-1);
    862 	}
    863 }
    864 
    865 
    866 ssize_t
    867 userspace_sctp_sendmbuf(struct socket *so,
    868     struct mbuf* mbufdata,
    869     size_t len,
    870     struct sockaddr *to,
    871     socklen_t tolen,
    872     u_int32_t ppid,
    873     u_int32_t flags,
    874     u_int16_t stream_no,
    875     u_int32_t timetolive,
    876     u_int32_t context)
    877 {
    878 
    879     struct sctp_sndrcvinfo sndrcvinfo, *sinfo = &sndrcvinfo;
    880     /*    struct uio auio;
    881           struct iovec iov[1]; */
    882     int error = 0;
    883     int uflags = 0;
    884     int retvalsendmsg;
    885 
    886     sinfo->sinfo_ppid = ppid;
    887     sinfo->sinfo_flags = flags;
    888     sinfo->sinfo_stream = stream_no;
    889     sinfo->sinfo_timetolive = timetolive;
    890     sinfo->sinfo_context = context;
    891     sinfo->sinfo_assoc_id = 0;
    892 
    893     /* Perform error checks on destination (to) */
    894     if (tolen > SOCK_MAXADDRLEN){
    895         error = (ENAMETOOLONG);
    896         goto sendmsg_return;
    897     }
    898     if (tolen < (socklen_t)offsetof(struct sockaddr, sa_data)){
    899         error = (EINVAL);
    900         goto sendmsg_return;
    901     }
    902     /* Adding the following as part of defensive programming, in case the application
    903        does not do it when preparing the destination address.*/
    904 #ifdef HAVE_SA_LEN
    905     to->sa_len = tolen;
    906 #endif
    907 
    908     error = sctp_lower_sosend(so, to, NULL/*uio*/,
    909                               (struct mbuf *)mbufdata, (struct mbuf *)NULL,
    910                               uflags, sinfo);
    911 sendmsg_return:
    912     /* TODO: Needs a condition for non-blocking when error is EWOULDBLOCK */
    913     if (0 == error)
    914         retvalsendmsg = len;
    915     else if(error == EWOULDBLOCK) {
    916         errno = EWOULDBLOCK;
    917         retvalsendmsg = (-1);
    918     } else {
    919         SCTP_PRINTF("%s: error = %d\n", __func__, error);
    920         errno = error;
    921         retvalsendmsg = (-1);
    922     }
    923     return retvalsendmsg;
    924 
    925 }
    926 
    927 
    928 /* taken from usr.lib/sctp_sys_calls.c and needed here */
    929 #define        SCTP_SMALL_IOVEC_SIZE 2
    930 
    931 /* Taken from  /src/lib/libc/net/sctp_sys_calls.c
    932  * and modified for __Userspace__
    933  * calling sctp_generic_recvmsg from this function
    934  */
    935 ssize_t
    936 userspace_sctp_recvmsg(struct socket *so,
    937     void *dbuf,
    938     size_t len,
    939     struct sockaddr *from,
    940     socklen_t *fromlenp,
    941     struct sctp_sndrcvinfo *sinfo,
    942     int *msg_flags)
    943 {
    944 	struct uio auio;
    945 	struct iovec iov[SCTP_SMALL_IOVEC_SIZE];
    946 	struct iovec *tiov;
    947 	int iovlen = 1;
    948 	int error = 0;
    949 	int ulen, i, retval;
    950 	socklen_t fromlen;
    951 
    952 	iov[0].iov_base = dbuf;
    953 	iov[0].iov_len = len;
    954 
    955 	auio.uio_iov = iov;
    956 	auio.uio_iovcnt = iovlen;
    957 	auio.uio_segflg = UIO_USERSPACE;
    958 	auio.uio_rw = UIO_READ;
    959 	auio.uio_offset = 0;			/* XXX */
    960 	auio.uio_resid = 0;
    961 	tiov = iov;
    962 	for (i = 0; i <iovlen; i++, tiov++) {
    963 		if ((auio.uio_resid += tiov->iov_len) < 0) {
    964 			error = EINVAL;
    965 			SCTP_PRINTF("%s: error = %d\n", __func__, error);
    966 			return (-1);
    967 		}
    968 	}
    969 	ulen = auio.uio_resid;
    970 	if (fromlenp != NULL) {
    971 		fromlen = *fromlenp;
    972 	} else {
    973 		fromlen = 0;
    974 	}
    975 	error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
    976 		    from, fromlen, msg_flags,
    977 		    (struct sctp_sndrcvinfo *)sinfo, 1);
    978 
    979 	if (error) {
    980 		if (auio.uio_resid != (int)ulen &&
    981 		    (error == EINTR ||
    982 #if !defined(__Userspace_os_NetBSD)
    983 		     error == ERESTART ||
    984 #endif
    985 		     error == EWOULDBLOCK)) {
    986 			error = 0;
    987 		}
    988 	}
    989 	if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
    990 		switch (from->sa_family) {
    991 #if defined(INET)
    992 		case AF_INET:
    993 			*fromlenp = sizeof(struct sockaddr_in);
    994 			break;
    995 #endif
    996 #if defined(INET6)
    997 		case AF_INET6:
    998 			*fromlenp = sizeof(struct sockaddr_in6);
    999 			break;
   1000 #endif
   1001 		case AF_CONN:
   1002 			*fromlenp = sizeof(struct sockaddr_conn);
   1003 			break;
   1004 		default:
   1005 			*fromlenp = 0;
   1006 			break;
   1007 		}
   1008 		if (*fromlenp > fromlen) {
   1009 			*fromlenp = fromlen;
   1010 		}
   1011 	}
   1012 	if (error == 0){
   1013 		/* ready return value */
   1014 		retval = (int)ulen - auio.uio_resid;
   1015 		return (retval);
   1016 	} else {
   1017 		SCTP_PRINTF("%s: error = %d\n", __func__, error);
   1018 		return (-1);
   1019 	}
   1020 }
   1021 
   1022 ssize_t
   1023 usrsctp_recvv(struct socket *so,
   1024     void *dbuf,
   1025     size_t len,
   1026     struct sockaddr *from,
   1027     socklen_t *fromlenp,
   1028     void *info,
   1029     socklen_t *infolen,
   1030     unsigned int *infotype,
   1031     int *msg_flags)
   1032 {
   1033 	struct uio auio;
   1034 	struct iovec iov[SCTP_SMALL_IOVEC_SIZE];
   1035 	struct iovec *tiov;
   1036 	int iovlen = 1;
   1037 	int ulen, i;
   1038 	socklen_t fromlen;
   1039 	struct sctp_rcvinfo *rcv;
   1040 	struct sctp_recvv_rn *rn;
   1041 	struct sctp_extrcvinfo seinfo;
   1042 
   1043 	if (so == NULL) {
   1044 		errno = EBADF;
   1045 		return (-1);
   1046 	}
   1047 	iov[0].iov_base = dbuf;
   1048 	iov[0].iov_len = len;
   1049 
   1050 	auio.uio_iov = iov;
   1051 	auio.uio_iovcnt = iovlen;
   1052 	auio.uio_segflg = UIO_USERSPACE;
   1053 	auio.uio_rw = UIO_READ;
   1054 	auio.uio_offset = 0;			/* XXX */
   1055 	auio.uio_resid = 0;
   1056 	tiov = iov;
   1057 	for (i = 0; i <iovlen; i++, tiov++) {
   1058 		if ((auio.uio_resid += tiov->iov_len) < 0) {
   1059 			errno = EINVAL;
   1060 			return (-1);
   1061 		}
   1062 	}
   1063 	ulen = auio.uio_resid;
   1064 	if (fromlenp != NULL) {
   1065 		fromlen = *fromlenp;
   1066 	} else {
   1067 		fromlen = 0;
   1068 	}
   1069 	errno = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
   1070 		    from, fromlen, msg_flags,
   1071 		    (struct sctp_sndrcvinfo *)&seinfo, 1);
   1072 	if (errno) {
   1073 		if (auio.uio_resid != (int)ulen &&
   1074 		    (errno == EINTR ||
   1075 #if !defined(__Userspace_os_NetBSD)
   1076 		     errno == ERESTART ||
   1077 #endif
   1078 		     errno == EWOULDBLOCK)) {
   1079 			errno = 0;
   1080 		}
   1081 	}
   1082 	if ((*msg_flags & MSG_NOTIFICATION) == 0) {
   1083 		struct sctp_inpcb *inp;
   1084 
   1085 		inp = (struct sctp_inpcb *)so->so_pcb;
   1086 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO) &&
   1087 		    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
   1088 		    *infolen >= (socklen_t)sizeof(struct sctp_recvv_rn) &&
   1089 		    seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_AVAIL) {
   1090 			rn = (struct sctp_recvv_rn *)info;
   1091 			rn->recvv_rcvinfo.rcv_sid = seinfo.sinfo_stream;
   1092 			rn->recvv_rcvinfo.rcv_ssn = seinfo.sinfo_ssn;
   1093 			rn->recvv_rcvinfo.rcv_flags = seinfo.sinfo_flags;
   1094 			rn->recvv_rcvinfo.rcv_ppid = seinfo.sinfo_ppid;
   1095 			rn->recvv_rcvinfo.rcv_context = seinfo.sinfo_context;
   1096 			rn->recvv_rcvinfo.rcv_tsn = seinfo.sinfo_tsn;
   1097 			rn->recvv_rcvinfo.rcv_cumtsn = seinfo.sinfo_cumtsn;
   1098 			rn->recvv_rcvinfo.rcv_assoc_id = seinfo.sinfo_assoc_id;
   1099 			rn->recvv_nxtinfo.nxt_sid = seinfo.sreinfo_next_stream;
   1100 			rn->recvv_nxtinfo.nxt_flags = 0;
   1101 			if (seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_IS_UNORDERED) {
   1102 				rn->recvv_nxtinfo.nxt_flags |= SCTP_UNORDERED;
   1103 			}
   1104 			if (seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_IS_NOTIFICATION) {
   1105 				rn->recvv_nxtinfo.nxt_flags |= SCTP_NOTIFICATION;
   1106 			}
   1107 			if (seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_ISCOMPLETE) {
   1108 				rn->recvv_nxtinfo.nxt_flags |= SCTP_COMPLETE;
   1109 			}
   1110 			rn->recvv_nxtinfo.nxt_ppid = seinfo.sreinfo_next_ppid;
   1111 			rn->recvv_nxtinfo.nxt_length = seinfo.sreinfo_next_length;
   1112 			rn->recvv_nxtinfo.nxt_assoc_id = seinfo.sreinfo_next_aid;
   1113 			*infolen = (socklen_t)sizeof(struct sctp_recvv_rn);
   1114 			*infotype = SCTP_RECVV_RN;
   1115 		} else if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
   1116 		           *infolen >= (socklen_t)sizeof(struct sctp_rcvinfo)) {
   1117 			rcv = (struct sctp_rcvinfo *)info;
   1118 			rcv->rcv_sid = seinfo.sinfo_stream;
   1119 			rcv->rcv_ssn = seinfo.sinfo_ssn;
   1120 			rcv->rcv_flags = seinfo.sinfo_flags;
   1121 			rcv->rcv_ppid = seinfo.sinfo_ppid;
   1122 			rcv->rcv_context = seinfo.sinfo_context;
   1123 			rcv->rcv_tsn = seinfo.sinfo_tsn;
   1124 			rcv->rcv_cumtsn = seinfo.sinfo_cumtsn;
   1125 			rcv->rcv_assoc_id = seinfo.sinfo_assoc_id;
   1126 			*infolen = (socklen_t)sizeof(struct sctp_rcvinfo);
   1127 			*infotype = SCTP_RECVV_RCVINFO;
   1128 		} else {
   1129 			*infotype = SCTP_RECVV_NOINFO;
   1130 			*infolen = 0;
   1131 		}
   1132 	}
   1133 	if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
   1134 		switch (from->sa_family) {
   1135 #if defined(INET)
   1136 		case AF_INET:
   1137 			*fromlenp = sizeof(struct sockaddr_in);
   1138 			break;
   1139 #endif
   1140 #if defined(INET6)
   1141 		case AF_INET6:
   1142 			*fromlenp = sizeof(struct sockaddr_in6);
   1143 			break;
   1144 #endif
   1145 		case AF_CONN:
   1146 			*fromlenp = sizeof(struct sockaddr_conn);
   1147 			break;
   1148 		default:
   1149 			*fromlenp = 0;
   1150 			break;
   1151 		}
   1152 		if (*fromlenp > fromlen) {
   1153 			*fromlenp = fromlen;
   1154 		}
   1155 	}
   1156 	if (errno == 0) {
   1157 		/* ready return value */
   1158 		return ((int)ulen - auio.uio_resid);
   1159 	} else {
   1160 		return (-1);
   1161 	}
   1162 }
   1163 
   1164 
   1165 
   1166 
   1167 #if defined(__Userspace__)
   1168 /* Taken from  /src/sys/kern/uipc_socket.c
   1169  * and modified for __Userspace__
   1170  * socreate returns a socket.  The socket should be
   1171  * closed with soclose().
   1172  */
   1173 int
   1174 socreate(int dom, struct socket **aso, int type, int proto)
   1175 {
   1176 	struct socket *so;
   1177 	int error;
   1178 
   1179 	if ((dom != AF_CONN) && (dom != AF_INET) && (dom != AF_INET6)) {
   1180 		return (EINVAL);
   1181 	}
   1182 	if ((type != SOCK_STREAM) && (type != SOCK_SEQPACKET)) {
   1183 		return (EINVAL);
   1184 	}
   1185 	if (proto != IPPROTO_SCTP) {
   1186 		return (EINVAL);
   1187 	}
   1188 
   1189 	so = soalloc();
   1190 	if (so == NULL) {
   1191 		return (ENOBUFS);
   1192 	}
   1193 
   1194 	/*
   1195 	 * so_incomp represents a queue of connections that
   1196 	 * must be completed at protocol level before being
   1197 	 * returned. so_comp field heads a list of sockets
   1198 	 * that are ready to be returned to the listening process
   1199 	 *__Userspace__ These queues are being used at a number of places like accept etc.
   1200 	 */
   1201 	TAILQ_INIT(&so->so_incomp);
   1202 	TAILQ_INIT(&so->so_comp);
   1203 	so->so_type = type;
   1204 	so->so_count = 1;
   1205 	so->so_dom = dom;
   1206 	/*
   1207 	 * Auto-sizing of socket buffers is managed by the protocols and
   1208 	 * the appropriate flags must be set in the pru_attach function.
   1209 	 * For __Userspace__ The pru_attach function in this case is sctp_attach.
   1210 	 */
   1211 	switch (dom) {
   1212 #if defined(INET)
   1213 	case AF_INET:
   1214 		error = sctp_attach(so, proto, SCTP_DEFAULT_VRFID);
   1215 		break;
   1216 #endif
   1217 #if defined(INET6)
   1218 	case AF_INET6:
   1219 		error = sctp6_attach(so, proto, SCTP_DEFAULT_VRFID);
   1220 		break;
   1221 #endif
   1222 	case AF_CONN:
   1223 		error = sctpconn_attach(so, proto, SCTP_DEFAULT_VRFID);
   1224 		break;
   1225 	default:
   1226 		error = EAFNOSUPPORT;
   1227 		break;
   1228 	}
   1229 	if (error) {
   1230 		KASSERT(so->so_count == 1, ("socreate: so_count %d", so->so_count));
   1231 		so->so_count = 0;
   1232 		sodealloc(so);
   1233 		return (error);
   1234 	}
   1235 	*aso = so;
   1236 	return (0);
   1237 }
   1238 #else
   1239 /* The kernel version for reference is below. The #else
   1240    should be removed once the __Userspace__
   1241    version is tested.
   1242  * socreate returns a socket with a ref count of 1.  The socket should be
   1243  * closed with soclose().
   1244  */
   1245 int
   1246 socreate(int dom, struct socket **aso, int type, int proto,
   1247     struct ucred *cred, struct thread *td)
   1248 {
   1249 	struct protosw *prp;
   1250 	struct socket *so;
   1251 	int error;
   1252 
   1253 	if (proto)
   1254 		prp = pffindproto(dom, proto, type);
   1255 	else
   1256 		prp = pffindtype(dom, type);
   1257 
   1258 	if (prp == NULL || prp->pr_usrreqs->pru_attach == NULL ||
   1259 	    prp->pr_usrreqs->pru_attach == pru_attach_notsupp)
   1260 		return (EPROTONOSUPPORT);
   1261 
   1262 	if (jailed(cred) && jail_socket_unixiproute_only &&
   1263 	    prp->pr_domain->dom_family != PF_LOCAL &&
   1264 	    prp->pr_domain->dom_family != PF_INET &&
   1265 	    prp->pr_domain->dom_family != PF_ROUTE) {
   1266 		return (EPROTONOSUPPORT);
   1267 	}
   1268 
   1269 	if (prp->pr_type != type)
   1270 		return (EPROTOTYPE);
   1271 	so = soalloc();
   1272 	if (so == NULL)
   1273 		return (ENOBUFS);
   1274 
   1275 	TAILQ_INIT(&so->so_incomp);
   1276 	TAILQ_INIT(&so->so_comp);
   1277 	so->so_type = type;
   1278 	so->so_cred = crhold(cred);
   1279 	so->so_proto = prp;
   1280 #ifdef MAC
   1281 	mac_create_socket(cred, so);
   1282 #endif
   1283 	knlist_init(&so->so_rcv.sb_sel.si_note, SOCKBUF_MTX(&so->so_rcv),
   1284 	    NULL, NULL, NULL);
   1285 	knlist_init(&so->so_snd.sb_sel.si_note, SOCKBUF_MTX(&so->so_snd),
   1286 	    NULL, NULL, NULL);
   1287 	so->so_count = 1;
   1288 	/*
   1289 	 * Auto-sizing of socket buffers is managed by the protocols and
   1290 	 * the appropriate flags must be set in the pru_attach function.
   1291 	 */
   1292 	error = (*prp->pr_usrreqs->pru_attach)(so, proto, td);
   1293 	if (error) {
   1294 		KASSERT(so->so_count == 1, ("socreate: so_count %d",
   1295 		    so->so_count));
   1296 		so->so_count = 0;
   1297 		sodealloc(so);
   1298 		return (error);
   1299 	}
   1300 	*aso = so;
   1301 	return (0);
   1302 }
   1303 #endif
   1304 
   1305 
   1306 
   1307 
   1308 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1309  * and modified for __Userspace__
   1310  * Removing struct thread td.
   1311  */
   1312 struct socket *
   1313 userspace_socket(int domain, int type, int protocol)
   1314 {
   1315 	struct socket *so = NULL;
   1316 
   1317 	errno = socreate(domain, &so, type, protocol);
   1318 	if (errno) {
   1319 		return (NULL);
   1320 	}
   1321 	/*
   1322 	 * The original socket call returns the file descriptor fd.
   1323 	 * td->td_retval[0] = fd.
   1324 	 * We are returning struct socket *so.
   1325 	 */
   1326 	return (so);
   1327 }
   1328 
   1329 struct socket *
   1330 usrsctp_socket(int domain, int type, int protocol,
   1331 	       int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
   1332                                  size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info),
   1333 	       int (*send_cb)(struct socket *sock, uint32_t sb_free),
   1334 	       uint32_t sb_threshold,
   1335 	       void *ulp_info)
   1336 {
   1337 	struct socket *so;
   1338 
   1339 	if ((protocol = IPPROTO_SCTP) && (SCTP_BASE_VAR(sctp_pcb_initialized) == 0)) {
   1340 		errno = EPROTONOSUPPORT;
   1341 		return (NULL);
   1342 	}
   1343 	if ((receive_cb == NULL) &&
   1344 	    ((send_cb != NULL) || (sb_threshold != 0) || (ulp_info != NULL))) {
   1345 		errno = EINVAL;
   1346 		return (NULL);
   1347 	}
   1348 	if ((domain == AF_CONN) && (SCTP_BASE_VAR(conn_output) == NULL)) {
   1349 		errno = EAFNOSUPPORT;
   1350 		return (NULL);
   1351 	}
   1352 	errno = socreate(domain, &so, type, protocol);
   1353 	if (errno) {
   1354 		return (NULL);
   1355 	}
   1356 	/*
   1357 	 * The original socket call returns the file descriptor fd.
   1358 	 * td->td_retval[0] = fd.
   1359 	 * We are returning struct socket *so.
   1360 	 */
   1361 	register_recv_cb(so, receive_cb);
   1362 	register_send_cb(so, sb_threshold, send_cb);
   1363 	register_ulp_info(so, ulp_info);
   1364 	return (so);
   1365 }
   1366 
   1367 
   1368 u_long	sb_max = SB_MAX;
   1369 u_long sb_max_adj =
   1370        SB_MAX * MCLBYTES / (MSIZE + MCLBYTES); /* adjusted sb_max */
   1371 
   1372 static	u_long sb_efficiency = 8;	/* parameter for sbreserve() */
   1373 
   1374 /*
   1375  * Allot mbufs to a sockbuf.  Attempt to scale mbmax so that mbcnt doesn't
   1376  * become limiting if buffering efficiency is near the normal case.
   1377  */
   1378 int
   1379 sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so)
   1380 {
   1381 	SOCKBUF_LOCK_ASSERT(sb);
   1382 	sb->sb_mbmax = (u_int)min(cc * sb_efficiency, sb_max);
   1383 	sb->sb_hiwat = cc;
   1384 	if (sb->sb_lowat > (int)sb->sb_hiwat)
   1385 		sb->sb_lowat = (int)sb->sb_hiwat;
   1386 	return (1);
   1387 }
   1388 
   1389 static int
   1390 sbreserve(struct sockbuf *sb, u_long cc, struct socket *so)
   1391 {
   1392 	int error;
   1393 
   1394 	SOCKBUF_LOCK(sb);
   1395 	error = sbreserve_locked(sb, cc, so);
   1396 	SOCKBUF_UNLOCK(sb);
   1397 	return (error);
   1398 }
   1399 
   1400 #if defined(__Userspace__)
   1401 int
   1402 soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
   1403 {
   1404 	SOCKBUF_LOCK(&so->so_snd);
   1405 	SOCKBUF_LOCK(&so->so_rcv);
   1406 	so->so_snd.sb_hiwat = (uint32_t)sndcc;
   1407 	so->so_rcv.sb_hiwat = (uint32_t)rcvcc;
   1408 
   1409 	if (sbreserve_locked(&so->so_snd, sndcc, so) == 0) {
   1410 		goto bad;
   1411 	}
   1412 	if (sbreserve_locked(&so->so_rcv, rcvcc, so) == 0) {
   1413 		goto bad;
   1414 	}
   1415 	if (so->so_rcv.sb_lowat == 0)
   1416 		so->so_rcv.sb_lowat = 1;
   1417 	if (so->so_snd.sb_lowat == 0)
   1418 		so->so_snd.sb_lowat = MCLBYTES;
   1419 	if (so->so_snd.sb_lowat > (int)so->so_snd.sb_hiwat)
   1420 		so->so_snd.sb_lowat = (int)so->so_snd.sb_hiwat;
   1421 	SOCKBUF_UNLOCK(&so->so_rcv);
   1422 	SOCKBUF_UNLOCK(&so->so_snd);
   1423 	return (0);
   1424 
   1425  bad:
   1426 	SOCKBUF_UNLOCK(&so->so_rcv);
   1427 	SOCKBUF_UNLOCK(&so->so_snd);
   1428 	return (ENOBUFS);
   1429 }
   1430 #else /* kernel version for reference */
   1431 int
   1432 soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
   1433 {
   1434 	struct thread *td = curthread;
   1435 
   1436 	SOCKBUF_LOCK(&so->so_snd);
   1437 	SOCKBUF_LOCK(&so->so_rcv);
   1438 	if (sbreserve_locked(&so->so_snd, sndcc, so, td) == 0)
   1439 		goto bad;
   1440 	if (sbreserve_locked(&so->so_rcv, rcvcc, so, td) == 0)
   1441 		goto bad2;
   1442 	if (so->so_rcv.sb_lowat == 0)
   1443 		so->so_rcv.sb_lowat = 1;
   1444 	if (so->so_snd.sb_lowat == 0)
   1445 		so->so_snd.sb_lowat = MCLBYTES;
   1446 	if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
   1447 		so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
   1448 	SOCKBUF_UNLOCK(&so->so_rcv);
   1449 	SOCKBUF_UNLOCK(&so->so_snd);
   1450 	return (0);
   1451 bad2:
   1452 	sbrelease_locked(&so->so_snd, so);
   1453 bad:
   1454 	SOCKBUF_UNLOCK(&so->so_rcv);
   1455 	SOCKBUF_UNLOCK(&so->so_snd);
   1456 	return (ENOBUFS);
   1457 }
   1458 #endif
   1459 
   1460 
   1461 
   1462 
   1463 
   1464 /* Taken from  /src/sys/kern/uipc_sockbuf.c
   1465  * and modified for __Userspace__
   1466  */
   1467 
   1468 #if defined(__Userspace__)
   1469 void
   1470 sowakeup(struct socket *so, struct sockbuf *sb)
   1471 {
   1472 
   1473 	SOCKBUF_LOCK_ASSERT(sb);
   1474 
   1475 	sb->sb_flags &= ~SB_SEL;
   1476 	if (sb->sb_flags & SB_WAIT) {
   1477 		sb->sb_flags &= ~SB_WAIT;
   1478 #if defined (__Userspace_os_Windows)
   1479 		WakeAllConditionVariable(&(sb)->sb_cond);
   1480 #else
   1481 		pthread_cond_broadcast(&(sb)->sb_cond);
   1482 #endif
   1483 	}
   1484 	SOCKBUF_UNLOCK(sb);
   1485 	/*__Userspace__ what todo about so_upcall?*/
   1486 
   1487 }
   1488 #else /* kernel version for reference */
   1489 /*
   1490  * Wakeup processes waiting on a socket buffer.  Do asynchronous notification
   1491  * via SIGIO if the socket has the SS_ASYNC flag set.
   1492  *
   1493  * Called with the socket buffer lock held; will release the lock by the end
   1494  * of the function.  This allows the caller to acquire the socket buffer lock
   1495  * while testing for the need for various sorts of wakeup and hold it through
   1496  * to the point where it's no longer required.  We currently hold the lock
   1497  * through calls out to other subsystems (with the exception of kqueue), and
   1498  * then release it to avoid lock order issues.  It's not clear that's
   1499  * correct.
   1500  */
   1501 void
   1502 sowakeup(struct socket *so, struct sockbuf *sb)
   1503 {
   1504 
   1505 	SOCKBUF_LOCK_ASSERT(sb);
   1506 
   1507 	selwakeuppri(&sb->sb_sel, PSOCK);
   1508 	sb->sb_flags &= ~SB_SEL;
   1509 	if (sb->sb_flags & SB_WAIT) {
   1510 		sb->sb_flags &= ~SB_WAIT;
   1511 		wakeup(&sb->sb_cc);
   1512 	}
   1513 	KNOTE_LOCKED(&sb->sb_sel.si_note, 0);
   1514 	SOCKBUF_UNLOCK(sb);
   1515 	if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL)
   1516 		pgsigio(&so->so_sigio, SIGIO, 0);
   1517 	if (sb->sb_flags & SB_UPCALL)
   1518 		(*so->so_upcall)(so, so->so_upcallarg, M_NOWAIT);
   1519 	if (sb->sb_flags & SB_AIO)
   1520 		aio_swake(so, sb);
   1521 	mtx_assert(SOCKBUF_MTX(sb), MA_NOTOWNED);
   1522 }
   1523 #endif
   1524 
   1525 
   1526 
   1527 /* Taken from  /src/sys/kern/uipc_socket.c
   1528  * and modified for __Userspace__
   1529  */
   1530 
   1531 int
   1532 sobind(struct socket *so, struct sockaddr *nam)
   1533 {
   1534 	switch (nam->sa_family) {
   1535 #if defined(INET)
   1536 	case AF_INET:
   1537 		return (sctp_bind(so, nam));
   1538 #endif
   1539 #if defined(INET6)
   1540 	case AF_INET6:
   1541 		return (sctp6_bind(so, nam, NULL));
   1542 #endif
   1543 	case AF_CONN:
   1544 		return (sctpconn_bind(so, nam));
   1545 	default:
   1546 		return EAFNOSUPPORT;
   1547 	}
   1548 }
   1549 
   1550 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1551  * and modified for __Userspace__
   1552  */
   1553 
   1554 int
   1555 usrsctp_bind(struct socket *so, struct sockaddr *name, int namelen)
   1556 {
   1557 	struct sockaddr *sa;
   1558 
   1559 	if (so == NULL) {
   1560 		errno = EBADF;
   1561 		return (-1);
   1562 	}
   1563 	if ((errno = getsockaddr(&sa, (caddr_t)name, namelen)) != 0)
   1564 		return (-1);
   1565 
   1566 	errno = sobind(so, sa);
   1567 	FREE(sa, M_SONAME);
   1568 	if (errno) {
   1569 		return (-1);
   1570 	} else {
   1571 		return (0);
   1572 	}
   1573 }
   1574 
   1575 int
   1576 userspace_bind(struct socket *so, struct sockaddr *name, int namelen)
   1577 {
   1578 	return (usrsctp_bind(so, name, namelen));
   1579 }
   1580 
   1581 /* Taken from  /src/sys/kern/uipc_socket.c
   1582  * and modified for __Userspace__
   1583  */
   1584 
   1585 int
   1586 solisten(struct socket *so, int backlog)
   1587 {
   1588 	if (so == NULL) {
   1589 		return (EBADF);
   1590 	} else {
   1591 		return (sctp_listen(so, backlog, NULL));
   1592 	}
   1593 }
   1594 
   1595 
   1596 int
   1597 solisten_proto_check(struct socket *so)
   1598 {
   1599 
   1600 	SOCK_LOCK_ASSERT(so);
   1601 
   1602 	if (so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |
   1603 	    SS_ISDISCONNECTING))
   1604 		return (EINVAL);
   1605 	return (0);
   1606 }
   1607 
   1608 static int somaxconn = SOMAXCONN;
   1609 
   1610 void
   1611 solisten_proto(struct socket *so, int backlog)
   1612 {
   1613 
   1614 	SOCK_LOCK_ASSERT(so);
   1615 
   1616 	if (backlog < 0 || backlog > somaxconn)
   1617 		backlog = somaxconn;
   1618 	so->so_qlimit = backlog;
   1619 	so->so_options |= SCTP_SO_ACCEPTCONN;
   1620 }
   1621 
   1622 
   1623 
   1624 
   1625 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1626  * and modified for __Userspace__
   1627  */
   1628 
   1629 int
   1630 usrsctp_listen(struct socket *so, int backlog)
   1631 {
   1632 	errno = solisten(so, backlog);
   1633 	if (errno) {
   1634 		return (-1);
   1635 	} else {
   1636 		return (0);
   1637 	}
   1638 }
   1639 
   1640 int
   1641 userspace_listen(struct socket *so, int backlog)
   1642 {
   1643 	return (usrsctp_listen(so, backlog));
   1644 }
   1645 
   1646 /* Taken from  /src/sys/kern/uipc_socket.c
   1647  * and modified for __Userspace__
   1648  */
   1649 
   1650 int
   1651 soaccept(struct socket *so, struct sockaddr **nam)
   1652 {
   1653 	int error;
   1654 
   1655 	SOCK_LOCK(so);
   1656 	KASSERT((so->so_state & SS_NOFDREF) != 0, ("soaccept: !NOFDREF"));
   1657 	so->so_state &= ~SS_NOFDREF;
   1658 	SOCK_UNLOCK(so);
   1659 	error = sctp_accept(so, nam);
   1660 	return (error);
   1661 }
   1662 
   1663 
   1664 
   1665 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1666  * kern_accept modified for __Userspace__
   1667  */
   1668 int
   1669 user_accept(struct socket *head,  struct sockaddr **name, socklen_t *namelen, struct socket **ptr_accept_ret_sock)
   1670 {
   1671 	struct sockaddr *sa = NULL;
   1672 	int error;
   1673 	struct socket *so = NULL;
   1674 
   1675 
   1676 	if (name) {
   1677 		*name = NULL;
   1678 	}
   1679 
   1680 	if ((head->so_options & SCTP_SO_ACCEPTCONN) == 0) {
   1681 		error = EINVAL;
   1682 		goto done;
   1683 	}
   1684 
   1685 	ACCEPT_LOCK();
   1686 	if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
   1687 		ACCEPT_UNLOCK();
   1688 		error = EWOULDBLOCK;
   1689 		goto noconnection;
   1690 	}
   1691 	while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
   1692 		if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
   1693 			head->so_error = ECONNABORTED;
   1694 			break;
   1695 		}
   1696 #if defined (__Userspace_os_Windows)
   1697 		if (SleepConditionVariableCS(&accept_cond, &accept_mtx, INFINITE))
   1698 			error = 0;
   1699 		else
   1700 			error = GetLastError();
   1701 #else
   1702 		error = pthread_cond_wait(&accept_cond, &accept_mtx);
   1703 #endif
   1704 		if (error) {
   1705 			ACCEPT_UNLOCK();
   1706 			goto noconnection;
   1707 		}
   1708 	}
   1709 	if (head->so_error) {
   1710 		error = head->so_error;
   1711 		head->so_error = 0;
   1712 		ACCEPT_UNLOCK();
   1713 		goto noconnection;
   1714 	}
   1715 	so = TAILQ_FIRST(&head->so_comp);
   1716 	KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
   1717 	KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
   1718 
   1719 	/*
   1720 	 * Before changing the flags on the socket, we have to bump the
   1721 	 * reference count.  Otherwise, if the protocol calls sofree(),
   1722 	 * the socket will be released due to a zero refcount.
   1723 	 */
   1724 	SOCK_LOCK(so);			/* soref() and so_state update */
   1725 	soref(so);			/* file descriptor reference */
   1726 
   1727 	TAILQ_REMOVE(&head->so_comp, so, so_list);
   1728 	head->so_qlen--;
   1729 	so->so_state |= (head->so_state & SS_NBIO);
   1730 	so->so_qstate &= ~SQ_COMP;
   1731 	so->so_head = NULL;
   1732 	SOCK_UNLOCK(so);
   1733 	ACCEPT_UNLOCK();
   1734 
   1735 
   1736 	/*
   1737 	 * The original accept returns fd value via td->td_retval[0] = fd;
   1738 	 * we will return the socket for accepted connection.
   1739 	 */
   1740 
   1741 	error = soaccept(so, &sa);
   1742 	if (error) {
   1743 		/*
   1744 		 * return a namelen of zero for older code which might
   1745 		 * ignore the return value from accept.
   1746 		 */
   1747 		if (name)
   1748 			*namelen = 0;
   1749 		goto noconnection;
   1750 	}
   1751 	if (sa == NULL) {
   1752 		if (name)
   1753 			*namelen = 0;
   1754 		goto done;
   1755 	}
   1756 	if (name) {
   1757 #ifdef HAVE_SA_LEN
   1758 		/* check sa_len before it is destroyed */
   1759 		if (*namelen > sa->sa_len) {
   1760 			*namelen = sa->sa_len;
   1761 		}
   1762 #else
   1763 		socklen_t sa_len;
   1764 
   1765 		switch (sa->sa_family) {
   1766 #ifdef INET
   1767 		case AF_INET:
   1768 			sa_len = sizeof(struct sockaddr_in);
   1769 			break;
   1770 #endif
   1771 #ifdef INET6
   1772 		case AF_INET6:
   1773 			sa_len = sizeof(struct sockaddr_in6);
   1774 			break;
   1775 #endif
   1776 		case AF_CONN:
   1777 			sa_len = sizeof(struct sockaddr_conn);
   1778 			break;
   1779 		default:
   1780 			sa_len = 0;
   1781 			break;
   1782 		}
   1783 		if (*namelen > sa_len) {
   1784 			*namelen = sa_len;
   1785 		}
   1786 #endif
   1787 		*name = sa;
   1788 		sa = NULL;
   1789 	}
   1790 noconnection:
   1791 	if (sa) {
   1792 		FREE(sa, M_SONAME);
   1793 	}
   1794 
   1795 done:
   1796 	*ptr_accept_ret_sock = so;
   1797 	return (error);
   1798 }
   1799 
   1800 
   1801 
   1802 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1803  * and modified for __Userspace__
   1804  */
   1805 /*
   1806  * accept1()
   1807  */
   1808 static int
   1809 accept1(struct socket *so, struct sockaddr *aname, socklen_t *anamelen, struct socket **ptr_accept_ret_sock)
   1810 {
   1811 	struct sockaddr *name;
   1812 	socklen_t namelen;
   1813 	int error;
   1814 
   1815 	if (so == NULL) {
   1816 		return (EBADF);
   1817 	}
   1818 	if (aname == NULL) {
   1819 		return (user_accept(so, NULL, NULL, ptr_accept_ret_sock));
   1820 	}
   1821 
   1822 	error = copyin(anamelen, &namelen, sizeof (namelen));
   1823 	if (error)
   1824 		return (error);
   1825 
   1826 	error = user_accept(so, &name, &namelen, ptr_accept_ret_sock);
   1827 
   1828 	/*
   1829 	 * return a namelen of zero for older code which might
   1830 	 * ignore the return value from accept.
   1831 	 */
   1832 	if (error) {
   1833 		(void) copyout(&namelen,
   1834 		    anamelen, sizeof(*anamelen));
   1835 		return (error);
   1836 	}
   1837 
   1838 	if (error == 0 && name != NULL) {
   1839 		error = copyout(name, aname, namelen);
   1840 	}
   1841 	if (error == 0) {
   1842 		error = copyout(&namelen, anamelen, sizeof(namelen));
   1843 	}
   1844 
   1845 	if (name) {
   1846 		FREE(name, M_SONAME);
   1847 	}
   1848 	return (error);
   1849 }
   1850 
   1851 struct socket *
   1852 usrsctp_accept(struct socket *so, struct sockaddr *aname, socklen_t *anamelen)
   1853 {
   1854 	struct socket *accept_return_sock;
   1855 
   1856 	errno = accept1(so, aname, anamelen, &accept_return_sock);
   1857 	if (errno) {
   1858 		return (NULL);
   1859 	} else {
   1860 		return (accept_return_sock);
   1861 	}
   1862 }
   1863 
   1864 struct socket *
   1865 userspace_accept(struct socket *so, struct sockaddr *aname, socklen_t *anamelen)
   1866 {
   1867 	return (usrsctp_accept(so, aname, anamelen));
   1868 }
   1869 
   1870 struct socket *
   1871 usrsctp_peeloff(struct socket *head, sctp_assoc_t id)
   1872 {
   1873 	struct socket *so;
   1874 
   1875 	if ((errno = sctp_can_peel_off(head, id)) != 0) {
   1876 		return (NULL);
   1877 	}
   1878 	if ((so = sonewconn(head, SS_ISCONNECTED)) == NULL) {
   1879 		return (NULL);
   1880 	}
   1881 	ACCEPT_LOCK();
   1882 	SOCK_LOCK(so);
   1883 	soref(so);
   1884 	TAILQ_REMOVE(&head->so_comp, so, so_list);
   1885 	head->so_qlen--;
   1886 	so->so_state |= (head->so_state & SS_NBIO);
   1887 	so->so_qstate &= ~SQ_COMP;
   1888 	so->so_head = NULL;
   1889 	SOCK_UNLOCK(so);
   1890 	ACCEPT_UNLOCK();
   1891 	if ((errno = sctp_do_peeloff(head, so, id)) != 0) {
   1892 		so->so_count = 0;
   1893 		sodealloc(so);
   1894 		return (NULL);
   1895 	}
   1896 	return (so);
   1897 }
   1898 
   1899 int
   1900 sodisconnect(struct socket *so)
   1901 {
   1902 	int error;
   1903 
   1904 	if ((so->so_state & SS_ISCONNECTED) == 0)
   1905 		return (ENOTCONN);
   1906 	if (so->so_state & SS_ISDISCONNECTING)
   1907 		return (EALREADY);
   1908 	error = sctp_disconnect(so);
   1909 	return (error);
   1910 }
   1911 
   1912 int
   1913 usrsctp_set_non_blocking(struct socket *so, int onoff)
   1914 {
   1915 	if (so == NULL) {
   1916 		errno = EBADF;
   1917 		return (-1);
   1918 	}
   1919 	SOCK_LOCK(so);
   1920 	if (onoff != 0) {
   1921 		so->so_state |= SS_NBIO;
   1922 	} else {
   1923 		so->so_state &= ~SS_NBIO;
   1924 	}
   1925 	SOCK_UNLOCK(so);
   1926 	return (0);
   1927 }
   1928 
   1929 int
   1930 usrsctp_get_non_blocking(struct socket *so)
   1931 {
   1932 	int result;
   1933 
   1934 	if (so == NULL) {
   1935 		errno = EBADF;
   1936 		return (-1);
   1937 	}
   1938 	SOCK_LOCK(so);
   1939 	if (so->so_state | SS_NBIO) {
   1940 		result = 1;
   1941 	} else {
   1942 		result = 0;
   1943 	}
   1944 	SOCK_UNLOCK(so);
   1945 	return (result);
   1946 }
   1947 
   1948 int
   1949 soconnect(struct socket *so, struct sockaddr *nam)
   1950 {
   1951 	int error;
   1952 
   1953 	if (so->so_options & SCTP_SO_ACCEPTCONN)
   1954 		return (EOPNOTSUPP);
   1955 	/*
   1956 	 * If protocol is connection-based, can only connect once.
   1957 	 * Otherwise, if connected, try to disconnect first.  This allows
   1958 	 * user to disconnect by connecting to, e.g., a null address.
   1959 	 */
   1960 	if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) && (error = sodisconnect(so))) {
   1961 		error = EISCONN;
   1962 	} else {
   1963 		/*
   1964 		 * Prevent accumulated error from previous connection from
   1965 		 * biting us.
   1966 		 */
   1967 		so->so_error = 0;
   1968 		switch (nam->sa_family) {
   1969 #if defined(INET)
   1970 		case AF_INET:
   1971 			error = sctp_connect(so, nam);
   1972 			break;
   1973 #endif
   1974 #if defined(INET6)
   1975 		case AF_INET6:
   1976 			error = sctp6_connect(so, nam);
   1977 			break;
   1978 #endif
   1979 		case AF_CONN:
   1980 			error = sctpconn_connect(so, nam);
   1981 			break;
   1982 		default:
   1983 			error = EAFNOSUPPORT;
   1984 		}
   1985 	}
   1986 
   1987 	return (error);
   1988 }
   1989 
   1990 
   1991 
   1992 int user_connect(struct socket *so, struct sockaddr *sa)
   1993 {
   1994 	int error;
   1995 	int interrupted = 0;
   1996 
   1997 	if (so == NULL) {
   1998 		error = EBADF;
   1999 		goto done1;
   2000 	}
   2001 	if (so->so_state & SS_ISCONNECTING) {
   2002 		error = EALREADY;
   2003 		goto done1;
   2004 	}
   2005 
   2006 	error = soconnect(so, sa);
   2007 	if (error) {
   2008 		goto bad;
   2009 	}
   2010 	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
   2011 		error = EINPROGRESS;
   2012 		goto done1;
   2013 	}
   2014 
   2015 	SOCK_LOCK(so);
   2016 	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
   2017 #if defined (__Userspace_os_Windows)
   2018 		if (SleepConditionVariableCS(SOCK_COND(so), SOCK_MTX(so), INFINITE))
   2019 			error = 0;
   2020 		else
   2021 			error = -1;
   2022 #else
   2023 		error = pthread_cond_wait(SOCK_COND(so), SOCK_MTX(so));
   2024 #endif
   2025 		if (error) {
   2026 #if defined(__Userspace_os_NetBSD)
   2027 			if (error == EINTR) {
   2028 #else
   2029 			if (error == EINTR || error == ERESTART) {
   2030 #endif
   2031 				interrupted = 1;
   2032 			}
   2033 			break;
   2034 		}
   2035 	}
   2036 	if (error == 0) {
   2037 		error = so->so_error;
   2038 		so->so_error = 0;
   2039 	}
   2040 	SOCK_UNLOCK(so);
   2041 
   2042 bad:
   2043 	if (!interrupted) {
   2044 		so->so_state &= ~SS_ISCONNECTING;
   2045 	}
   2046 #if !defined(__Userspace_os_NetBSD)
   2047 	if (error == ERESTART) {
   2048 		error = EINTR;
   2049 	}
   2050 #endif
   2051 done1:
   2052 	return (error);
   2053 }
   2054 
   2055 int usrsctp_connect(struct socket *so, struct sockaddr *name, int namelen)
   2056 {
   2057 	struct sockaddr *sa;
   2058 
   2059 	errno = getsockaddr(&sa, (caddr_t)name, namelen);
   2060 	if (errno)
   2061 		return (-1);
   2062 
   2063 	errno = user_connect(so, sa);
   2064 	FREE(sa, M_SONAME);
   2065 	if (errno) {
   2066 		return (-1);
   2067 	} else {
   2068 		return (0);
   2069 	}
   2070 }
   2071 
   2072 int userspace_connect(struct socket *so, struct sockaddr *name, int namelen)
   2073 {
   2074 	return (usrsctp_connect(so, name, namelen));
   2075 }
   2076 
   2077 #define SCTP_STACK_BUF_SIZE         2048
   2078 
   2079 void
   2080 usrsctp_close(struct socket *so) {
   2081 	if (so != NULL) {
   2082 		if (so->so_options & SCTP_SO_ACCEPTCONN) {
   2083 			struct socket *sp;
   2084 
   2085 			ACCEPT_LOCK();
   2086 			while ((sp = TAILQ_FIRST(&so->so_comp)) != NULL) {
   2087 				TAILQ_REMOVE(&so->so_comp, sp, so_list);
   2088 				so->so_qlen--;
   2089 				sp->so_qstate &= ~SQ_COMP;
   2090 				sp->so_head = NULL;
   2091 				ACCEPT_UNLOCK();
   2092 				soabort(sp);
   2093 				ACCEPT_LOCK();
   2094 			}
   2095 			ACCEPT_UNLOCK();
   2096 		}
   2097 		ACCEPT_LOCK();
   2098 		SOCK_LOCK(so);
   2099 		sorele(so);
   2100 	}
   2101 }
   2102 
   2103 void
   2104 userspace_close(struct socket *so)
   2105 {
   2106 	usrsctp_close(so);
   2107 }
   2108 
   2109 int
   2110 usrsctp_shutdown(struct socket *so, int how)
   2111 {
   2112 	if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR)) {
   2113 		errno = EINVAL;
   2114 		return (-1);
   2115 	}
   2116 	if (so == NULL) {
   2117 		errno = EBADF;
   2118 		return (-1);
   2119 	}
   2120 	sctp_flush(so, how);
   2121 	if (how != SHUT_WR)
   2122 		 socantrcvmore(so);
   2123 	if (how != SHUT_RD) {
   2124 		errno = sctp_shutdown(so);
   2125 		if (errno) {
   2126 			return (-1);
   2127 		} else {
   2128 			return (0);
   2129 		}
   2130 	}
   2131 	return (0);
   2132 }
   2133 
   2134 int
   2135 userspace_shutdown(struct socket *so, int how)
   2136 {
   2137 	return (usrsctp_shutdown(so, how));
   2138 }
   2139 
   2140 int
   2141 usrsctp_finish(void)
   2142 {
   2143 	if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
   2144 		return (0);
   2145 	}
   2146 	if (SCTP_INP_INFO_TRYLOCK()) {
   2147 		if (!LIST_EMPTY(&SCTP_BASE_INFO(listhead))) {
   2148 			SCTP_INP_INFO_RUNLOCK();
   2149 			return (-1);
   2150 		}
   2151 		SCTP_INP_INFO_RUNLOCK();
   2152 	} else {
   2153 		return (-1);
   2154 	}
   2155 	sctp_finish();
   2156 	return (0);
   2157 }
   2158 
   2159 int
   2160 userspace_finish(void)
   2161 {
   2162 	return (usrsctp_finish());
   2163 }
   2164 
   2165 /* needed from sctp_usrreq.c */
   2166 int
   2167 sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, void *p);
   2168 
   2169 int
   2170 usrsctp_setsockopt(struct socket *so, int level, int option_name,
   2171                    const void *option_value, socklen_t option_len)
   2172 {
   2173 	if (so == NULL) {
   2174 		errno = EBADF;
   2175 		return (-1);
   2176 	}
   2177 	switch (level) {
   2178 	case SOL_SOCKET:
   2179 	{
   2180 		switch (option_name) {
   2181 		case SO_RCVBUF:
   2182 			if (option_len < (socklen_t)sizeof(int)) {
   2183 				errno = EINVAL;
   2184 				return (-1);
   2185 			} else {
   2186 				int *buf_size;
   2187 
   2188 				buf_size = (int *)option_value;
   2189 				if (*buf_size < 1) {
   2190 					errno = EINVAL;
   2191 					return (-1);
   2192 				}
   2193 				sbreserve(&so->so_rcv, (u_long)*buf_size, so);
   2194 				return (0);
   2195 			}
   2196 			break;
   2197 		case SO_SNDBUF:
   2198 			if (option_len < (socklen_t)sizeof(int)) {
   2199 				errno = EINVAL;
   2200 				return (-1);
   2201 			} else {
   2202 				int *buf_size;
   2203 
   2204 				buf_size = (int *)option_value;
   2205 				if (*buf_size < 1) {
   2206 					errno = EINVAL;
   2207 					return (-1);
   2208 				}
   2209 				sbreserve(&so->so_snd, (u_long)*buf_size, so);
   2210 				return (0);
   2211 			}
   2212 			break;
   2213 		case SO_LINGER:
   2214 			if (option_len < (socklen_t)sizeof(struct linger)) {
   2215 				errno = EINVAL;
   2216 				return (-1);
   2217 			} else {
   2218 				struct linger *l;
   2219 
   2220 				l = (struct linger *)option_value;
   2221 				so->so_linger = l->l_linger;
   2222 				if (l->l_onoff) {
   2223 					so->so_options |= SCTP_SO_LINGER;
   2224 				} else {
   2225 					so->so_options &= ~SCTP_SO_LINGER;
   2226 				}
   2227 				return (0);
   2228 			}
   2229 		default:
   2230 			errno = EINVAL;
   2231 			return (-1);
   2232 		}
   2233 	}
   2234 	case IPPROTO_SCTP:
   2235 		errno = sctp_setopt(so, option_name, (void *) option_value, (size_t)option_len, NULL);
   2236 		if (errno) {
   2237 			return (-1);
   2238 		} else {
   2239 			return (0);
   2240 		}
   2241 	default:
   2242 		errno = ENOPROTOOPT;
   2243 		return (-1);
   2244 	}
   2245 }
   2246 
   2247 int
   2248 userspace_setsockopt(struct socket *so, int level, int option_name,
   2249                      const void *option_value, socklen_t option_len)
   2250 {
   2251 	return (usrsctp_setsockopt(so, level, option_name, option_value, option_len));
   2252 }
   2253 
   2254 /* needed from sctp_usrreq.c */
   2255 int
   2256 sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
   2257 	    void *p);
   2258 
   2259 int
   2260 usrsctp_getsockopt(struct socket *so, int level, int option_name,
   2261                    void *option_value, socklen_t *option_len)
   2262 {
   2263 	if (so == NULL) {
   2264 		errno = EBADF;
   2265 		return (-1);
   2266 	}
   2267 	if (option_len == NULL) {
   2268 		errno = EFAULT;
   2269 		return (-1);
   2270 	}
   2271 	switch (level) {
   2272 	case SOL_SOCKET:
   2273 		switch (option_name) {
   2274 		case SO_RCVBUF:
   2275 			if (*option_len < (socklen_t)sizeof(int)) {
   2276 				errno = EINVAL;
   2277 				return (-1);
   2278 			} else {
   2279 				int *buf_size;
   2280 
   2281 				buf_size = (int *)option_value;
   2282 				*buf_size = so->so_rcv.sb_hiwat;;
   2283 				*option_len = (socklen_t)sizeof(int);
   2284 				return (0);
   2285 			}
   2286 			break;
   2287 		case SO_SNDBUF:
   2288 			if (*option_len < (socklen_t)sizeof(int)) {
   2289 				errno = EINVAL;
   2290 				return (-1);
   2291 			} else {
   2292 				int *buf_size;
   2293 
   2294 				buf_size = (int *)option_value;
   2295 				*buf_size = so->so_snd.sb_hiwat;
   2296 				*option_len = (socklen_t)sizeof(int);
   2297 				return (0);
   2298 			}
   2299 			break;
   2300 		case SO_LINGER:
   2301 			if (*option_len < (socklen_t)sizeof(struct linger)) {
   2302 				errno = EINVAL;
   2303 				return (-1);
   2304 			} else {
   2305 				struct linger *l;
   2306 
   2307 				l = (struct linger *)option_value;
   2308 				l->l_linger = so->so_linger;
   2309 				if (so->so_options & SCTP_SO_LINGER) {
   2310 					l->l_onoff = 1;
   2311 				} else {
   2312 					l->l_onoff = 0;
   2313 				}
   2314 				*option_len = (socklen_t)sizeof(struct linger);
   2315 				return (0);
   2316 			}
   2317 		default:
   2318 			errno = EINVAL;
   2319 			return (-1);
   2320 		}
   2321 	case IPPROTO_SCTP:
   2322 	{
   2323 		size_t len;
   2324 
   2325 		len = (size_t)*option_len;
   2326 		errno = sctp_getopt(so, option_name, option_value, &len, NULL);
   2327 		*option_len = (socklen_t)len;
   2328 		if (errno) {
   2329 			return (-1);
   2330 		} else {
   2331 			return (0);
   2332 		}
   2333 	}
   2334 	default:
   2335 		errno = ENOPROTOOPT;
   2336 		return (-1);
   2337 	}
   2338 }
   2339 
   2340 int
   2341 userspace_getsockopt(struct socket *so, int level, int option_name,
   2342                      void *option_value, socklen_t *option_len)
   2343 {
   2344 	return (usrsctp_getsockopt(so, level, option_name, option_value, option_len));
   2345 }
   2346 
   2347 int
   2348 usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
   2349 {
   2350 	struct sctp_getaddresses *gaddrs;
   2351 	struct sockaddr *sa;
   2352 #ifdef INET
   2353 	struct sockaddr_in *sin;
   2354 #endif
   2355 #ifdef INET6
   2356 	struct sockaddr_in6 *sin6;
   2357 #endif
   2358 	int i;
   2359 	size_t argsz;
   2360 #if defined(INET) || defined(INET6)
   2361 	uint16_t sport = 0;
   2362 #endif
   2363 
   2364 	/* validate the flags */
   2365 	if ((flags != SCTP_BINDX_ADD_ADDR) &&
   2366 	    (flags != SCTP_BINDX_REM_ADDR)) {
   2367 		errno = EFAULT;
   2368 		return (-1);
   2369 	}
   2370 	/* validate the address count and list */
   2371 	if ((addrcnt <= 0) || (addrs == NULL)) {
   2372 		errno = EINVAL;
   2373 		return (-1);
   2374 	}
   2375 	/* First pre-screen the addresses */
   2376 	sa = addrs;
   2377 	for (i = 0; i < addrcnt; i++) {
   2378 		switch (sa->sa_family) {
   2379 #ifdef INET
   2380 		case AF_INET:
   2381 #ifdef HAVE_SA_LEN
   2382 			if (sa->sa_len != sizeof(struct sockaddr_in)) {
   2383 				errno = EINVAL;
   2384 				return (-1);
   2385 			}
   2386 #endif
   2387 			sin = (struct sockaddr_in *)sa;
   2388 			if (sin->sin_port) {
   2389 				/* non-zero port, check or save */
   2390 				if (sport) {
   2391 					/* Check against our port */
   2392 					if (sport != sin->sin_port) {
   2393 						errno = EINVAL;
   2394 						return (-1);
   2395 					}
   2396 				} else {
   2397 					/* save off the port */
   2398 					sport = sin->sin_port;
   2399 				}
   2400 			}
   2401 #ifndef HAVE_SA_LEN
   2402 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
   2403 #endif
   2404 			break;
   2405 #endif
   2406 #ifdef INET6
   2407 		case AF_INET6:
   2408 #ifdef HAVE_SA_LEN
   2409 			if (sa->sa_len != sizeof(struct sockaddr_in6)) {
   2410 				errno = EINVAL;
   2411 				return (-1);
   2412 			}
   2413 #endif
   2414 			sin6 = (struct sockaddr_in6 *)sa;
   2415 			if (sin6->sin6_port) {
   2416 				/* non-zero port, check or save */
   2417 				if (sport) {
   2418 					/* Check against our port */
   2419 					if (sport != sin6->sin6_port) {
   2420 						errno = EINVAL;
   2421 						return (-1);
   2422 					}
   2423 				} else {
   2424 					/* save off the port */
   2425 					sport = sin6->sin6_port;
   2426 				}
   2427 			}
   2428 #ifndef HAVE_SA_LEN
   2429 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
   2430 #endif
   2431 			break;
   2432 #endif
   2433 		default:
   2434 			/* Invalid address family specified. */
   2435 			errno = EAFNOSUPPORT;
   2436 			return (-1);
   2437 		}
   2438 #ifdef HAVE_SA_LEN
   2439 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2440 #endif
   2441 	}
   2442 	argsz = sizeof(struct sctp_getaddresses) +
   2443 	        sizeof(struct sockaddr_storage);
   2444 	if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) {
   2445 		errno = ENOMEM;
   2446 		return (-1);
   2447 	}
   2448 	sa = addrs;
   2449 	for (i = 0; i < addrcnt; i++) {
   2450 #ifndef HAVE_SA_LEN
   2451 		size_t sa_len;
   2452 #endif
   2453 		memset(gaddrs, 0, argsz);
   2454 		gaddrs->sget_assoc_id = 0;
   2455 #ifdef HAVE_SA_LEN
   2456 		memcpy(gaddrs->addr, sa, sa->sa_len);
   2457 		if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
   2458 			free(gaddrs);
   2459 			return (-1);
   2460 		}
   2461 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2462 #else
   2463 		switch (sa->sa_family) {
   2464 #ifdef INET
   2465 		case AF_INET:
   2466 			sa_len = sizeof(struct sockaddr_in);
   2467 			break;
   2468 #endif
   2469 #ifdef INET6
   2470 		case AF_INET6:
   2471 			sa_len = sizeof(struct sockaddr_in6);
   2472 			break;
   2473 #endif
   2474 		default:
   2475 			sa_len = 0;
   2476 			break;
   2477 		}
   2478 		memcpy(gaddrs->addr, sa, sa_len);
   2479 		/*
   2480 		 * Now, if there was a port mentioned, assure that the
   2481 		 * first address has that port to make sure it fails or
   2482 		 * succeeds correctly.
   2483 		 */
   2484 #if defined(INET) || defined(INET6)
   2485 		if ((i == 0) && (sport != 0)) {
   2486 			switch (gaddrs->addr->sa_family) {
   2487 #ifdef INET
   2488 			case AF_INET:
   2489 				sin = (struct sockaddr_in *)gaddrs->addr;
   2490 				sin->sin_port = sport;
   2491 				break;
   2492 #endif
   2493 #ifdef INET6
   2494 			case AF_INET6:
   2495 				sin6 = (struct sockaddr_in6 *)gaddrs->addr;
   2496 				sin6->sin6_port = sport;
   2497 				break;
   2498 #endif
   2499 			}
   2500 		}
   2501 #endif
   2502 		if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
   2503 			free(gaddrs);
   2504 			return (-1);
   2505 		}
   2506 		sa = (struct sockaddr *)((caddr_t)sa + sa_len);
   2507 #endif
   2508 	}
   2509 	free(gaddrs);
   2510 	return (0);
   2511 }
   2512 
   2513 int
   2514 usrsctp_connectx(struct socket *so,
   2515                  const struct sockaddr *addrs, int addrcnt,
   2516                  sctp_assoc_t *id)
   2517 {
   2518 #if defined(INET) || defined(INET6)
   2519 	char buf[SCTP_STACK_BUF_SIZE];
   2520 	int i, ret, cnt, *aa;
   2521 	char *cpto;
   2522 	const struct sockaddr *at;
   2523 	sctp_assoc_t *p_id;
   2524 	size_t len = sizeof(int);
   2525 
   2526 	/* validate the address count and list */
   2527 	if ((addrs == NULL) || (addrcnt <= 0)) {
   2528 		errno = EINVAL;
   2529 		return (-1);
   2530 	}
   2531 	at = addrs;
   2532 	cnt = 0;
   2533 	cpto = ((caddr_t)buf + sizeof(int));
   2534 	/* validate all the addresses and get the size */
   2535 	for (i = 0; i < addrcnt; i++) {
   2536 		switch (at->sa_family) {
   2537 #ifdef INET
   2538 		case AF_INET:
   2539 #ifdef HAVE_SA_LEN
   2540 			if (at->sa_len != sizeof(struct sockaddr_in)) {
   2541 				errno = EINVAL;
   2542 				return (-1);
   2543 			}
   2544 #endif
   2545 			memcpy(cpto, at, sizeof(struct sockaddr_in));
   2546 			cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
   2547 			len += sizeof(struct sockaddr_in);
   2548 			at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in));
   2549 			break;
   2550 #endif
   2551 #ifdef INET6
   2552 		case AF_INET6:
   2553 #ifdef HAVE_SA_LEN
   2554 			if (at->sa_len != sizeof(struct sockaddr_in6)) {
   2555 				errno = EINVAL;
   2556 				return (-1);
   2557 			}
   2558 #endif
   2559 			if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)at)->sin6_addr)) {
   2560 				in6_sin6_2_sin((struct sockaddr_in *)cpto, (struct sockaddr_in6 *)at);
   2561 				cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
   2562 				len += sizeof(struct sockaddr_in);
   2563 			} else {
   2564 				memcpy(cpto, at, sizeof(struct sockaddr_in6));
   2565 				cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6));
   2566 				len += sizeof(struct sockaddr_in6);
   2567 			}
   2568 			at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in6));
   2569 			break;
   2570 #endif
   2571 		default:
   2572 			errno = EINVAL;
   2573 			return (-1);
   2574 		}
   2575 		if (len > (sizeof(buf) - sizeof(int))) {
   2576 			/* Never enough memory */
   2577 			errno = E2BIG;
   2578 			return (-1);
   2579 		}
   2580 		cnt++;
   2581 	}
   2582 	/* do we have any? */
   2583 	if (cnt == 0) {
   2584 		errno = EINVAL;
   2585 		return (-1);
   2586 	}
   2587 	aa = (int *)buf;
   2588 	*aa = cnt;
   2589 	ret = usrsctp_setsockopt(so, IPPROTO_SCTP, SCTP_CONNECT_X, (void *)buf, (socklen_t)len);
   2590 	if ((ret == 0) && id) {
   2591 		p_id = (sctp_assoc_t *)buf;
   2592 		*id = *p_id;
   2593 	}
   2594 	return (ret);
   2595 #else
   2596 	errno = EINVAL;
   2597 	return (-1);
   2598 #endif
   2599 }
   2600 
   2601 int
   2602 usrsctp_getpaddrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
   2603 {
   2604 	struct sctp_getaddresses *addrs;
   2605 	struct sockaddr *sa;
   2606 	sctp_assoc_t asoc;
   2607 	caddr_t lim;
   2608 	socklen_t opt_len;
   2609 	int cnt;
   2610 
   2611 	if (raddrs == NULL) {
   2612 		errno = EFAULT;
   2613 		return (-1);
   2614 	}
   2615 	asoc = id;
   2616 	opt_len = (socklen_t)sizeof(sctp_assoc_t);
   2617 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE, &asoc, &opt_len) != 0) {
   2618 		return (-1);
   2619 	}
   2620 	/* size required is returned in 'asoc' */
   2621 	opt_len = (socklen_t)((size_t)asoc + sizeof(struct sctp_getaddresses));
   2622 	addrs = calloc(1, (size_t)opt_len);
   2623 	if (addrs == NULL) {
   2624 		errno = ENOMEM;
   2625 		return (-1);
   2626 	}
   2627 	addrs->sget_assoc_id = id;
   2628 	/* Now lets get the array of addresses */
   2629 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_PEER_ADDRESSES, addrs, &opt_len) != 0) {
   2630 		free(addrs);
   2631 		return (-1);
   2632 	}
   2633 	*raddrs = (struct sockaddr *)&addrs->addr[0];
   2634 	cnt = 0;
   2635 	sa = (struct sockaddr *)&addrs->addr[0];
   2636 	lim = (caddr_t)addrs + opt_len;
   2637 #ifdef HAVE_SA_LEN
   2638 	while (((caddr_t)sa < lim) && (sa->sa_len > 0)) {
   2639 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2640 #else
   2641 	while ((caddr_t)sa < lim) {
   2642 		switch (sa->sa_family) {
   2643 #ifdef INET
   2644 		case AF_INET:
   2645 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
   2646 			break;
   2647 #endif
   2648 #ifdef INET6
   2649 		case AF_INET6:
   2650 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
   2651 			break;
   2652 #endif
   2653 		case AF_CONN:
   2654 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_conn));
   2655 			break;
   2656 		default:
   2657 			return (cnt);
   2658 			break;
   2659 		}
   2660 #endif
   2661 		cnt++;
   2662 	}
   2663 	return (cnt);
   2664 }
   2665 
   2666 void
   2667 usrsctp_freepaddrs(struct sockaddr *addrs)
   2668 {
   2669 	/* Take away the hidden association id */
   2670 	void *fr_addr;
   2671 
   2672 	fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
   2673 	/* Now free it */
   2674 	free(fr_addr);
   2675 }
   2676 
   2677 int
   2678 usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
   2679 {
   2680 	struct sctp_getaddresses *addrs;
   2681 	caddr_t lim;
   2682 	struct sockaddr *sa;
   2683 	size_t size_of_addresses;
   2684 	socklen_t opt_len;
   2685 	int cnt;
   2686 
   2687 	if (raddrs == NULL) {
   2688 		errno = EFAULT;
   2689 		return (-1);
   2690 	}
   2691 	size_of_addresses = 0;
   2692 	opt_len = (socklen_t)sizeof(int);
   2693 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDR_SIZE, &size_of_addresses, &opt_len) != 0) {
   2694 		errno = ENOMEM;
   2695 		return (-1);
   2696 	}
   2697 	if (size_of_addresses == 0) {
   2698 		errno = ENOTCONN;
   2699 		return (-1);
   2700 	}
   2701 	opt_len = (socklen_t)(size_of_addresses +
   2702 	                      sizeof(struct sockaddr_storage) +
   2703 	                      sizeof(struct sctp_getaddresses));
   2704 	addrs = calloc(1, (size_t)opt_len);
   2705 	if (addrs == NULL) {
   2706 		errno = ENOMEM;
   2707 		return (-1);
   2708 	}
   2709 	addrs->sget_assoc_id = id;
   2710 	/* Now lets get the array of addresses */
   2711 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDRESSES, addrs, &opt_len) != 0) {
   2712 		free(addrs);
   2713 		errno = ENOMEM;
   2714 		return (-1);
   2715 	}
   2716 	*raddrs = (struct sockaddr *)&addrs->addr[0];
   2717 	cnt = 0;
   2718 	sa = (struct sockaddr *)&addrs->addr[0];
   2719 	lim = (caddr_t)addrs + opt_len;
   2720 #ifdef HAVE_SA_LEN
   2721 	while (((caddr_t)sa < lim) && (sa->sa_len > 0)) {
   2722 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2723 #else
   2724 	while ((caddr_t)sa < lim) {
   2725 		switch (sa->sa_family) {
   2726 #ifdef INET
   2727 		case AF_INET:
   2728 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
   2729 			break;
   2730 #endif
   2731 #ifdef INET6
   2732 		case AF_INET6:
   2733 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
   2734 			break;
   2735 #endif
   2736 		case AF_CONN:
   2737 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_conn));
   2738 			break;
   2739 		default:
   2740 			return (cnt);
   2741 			break;
   2742 		}
   2743 #endif
   2744 		cnt++;
   2745 	}
   2746 	return (cnt);
   2747 }
   2748 
   2749 void
   2750 usrsctp_freeladdrs(struct sockaddr *addrs)
   2751 {
   2752 	/* Take away the hidden association id */
   2753 	void *fr_addr;
   2754 
   2755 	fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
   2756 	/* Now free it */
   2757 	free(fr_addr);
   2758 }
   2759 
   2760 #ifdef INET
   2761 void
   2762 sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
   2763                          sctp_route_t *ro, void *stcb,
   2764                          uint32_t vrf_id)
   2765 {
   2766 	struct mbuf *m;
   2767 	struct mbuf *m_orig;
   2768 	int iovcnt;
   2769 	int send_len;
   2770 	int len;
   2771 	int send_count;
   2772 	struct ip *ip;
   2773 	struct udphdr *udp;
   2774 #if !defined (__Userspace_os_Windows)
   2775 	int res;
   2776 #endif
   2777 	struct sockaddr_in dst;
   2778 #if defined (__Userspace_os_Windows)
   2779 	WSAMSG win_msg_hdr;
   2780 	int win_sent_len;
   2781 	WSABUF send_iovec[MAXLEN_MBUF_CHAIN];
   2782 	WSABUF winbuf;
   2783 #else
   2784 	struct iovec send_iovec[MAXLEN_MBUF_CHAIN];
   2785 	struct msghdr msg_hdr;
   2786 #endif
   2787 	int use_udp_tunneling;
   2788 
   2789 	*result = 0;
   2790 
   2791 	m = SCTP_HEADER_TO_CHAIN(o_pak);
   2792 	m_orig = m;
   2793 
   2794 	len = sizeof(struct ip);
   2795 	if (SCTP_BUF_LEN(m) < len) {
   2796 		if ((m = m_pullup(m, len)) == 0) {
   2797 			SCTP_PRINTF("Can not get the IP header in the first mbuf.\n");
   2798 			return;
   2799 		}
   2800 	}
   2801 	ip = mtod(m, struct ip *);
   2802 	use_udp_tunneling = (ip->ip_p == IPPROTO_UDP);
   2803 
   2804 	if (use_udp_tunneling) {
   2805 		len = sizeof(struct ip) + sizeof(struct udphdr);
   2806 		if (SCTP_BUF_LEN(m) < len) {
   2807 			if ((m = m_pullup(m, len)) == 0) {
   2808 				SCTP_PRINTF("Can not get the UDP/IP header in the first mbuf.\n");
   2809 				return;
   2810 			}
   2811 			ip = mtod(m, struct ip *);
   2812 		}
   2813 		udp = (struct udphdr *)(ip + 1);
   2814 	} else {
   2815 		udp = NULL;
   2816 	}
   2817 
   2818 	if (!use_udp_tunneling) {
   2819 		if (ip->ip_src.s_addr == INADDR_ANY) {
   2820 			/* TODO get addr of outgoing interface */
   2821 			SCTP_PRINTF("Why did the SCTP implementation did not choose a source address?\n");
   2822 		}
   2823 		/* TODO need to worry about ro->ro_dst as in ip_output? */
   2824 #if defined(__Userspace_os_Linux) || defined (__Userspace_os_Windows)
   2825 		/* need to put certain fields into network order for Linux */
   2826 		ip->ip_len = htons(ip->ip_len);
   2827 		ip->ip_off = 0;
   2828 #endif
   2829 	}
   2830 
   2831 	memset((void *)&dst, 0, sizeof(struct sockaddr_in));
   2832 	dst.sin_family = AF_INET;
   2833 	dst.sin_addr.s_addr = ip->ip_dst.s_addr;
   2834 #ifdef HAVE_SIN_LEN
   2835 	dst.sin_len = sizeof(struct sockaddr_in);
   2836 #endif
   2837 	if (use_udp_tunneling) {
   2838 		dst.sin_port = udp->uh_dport;
   2839 	} else {
   2840 		dst.sin_port = 0;
   2841 	}
   2842 
   2843 	/* tweak the mbuf chain */
   2844 	if (use_udp_tunneling) {
   2845 		m_adj(m, sizeof(struct ip) + sizeof(struct udphdr));
   2846 	}
   2847 
   2848 	send_len = SCTP_HEADER_LEN(m); /* length of entire packet */
   2849 	send_count = 0;
   2850 	for (iovcnt = 0; m != NULL && iovcnt < MAXLEN_MBUF_CHAIN; m = m->m_next, iovcnt++) {
   2851 #if !defined (__Userspace_os_Windows)
   2852 		send_iovec[iovcnt].iov_base = (caddr_t)m->m_data;
   2853 		send_iovec[iovcnt].iov_len = SCTP_BUF_LEN(m);
   2854 		send_count += send_iovec[iovcnt].iov_len;
   2855 #else
   2856 		send_iovec[iovcnt].buf = (caddr_t)m->m_data;
   2857 		send_iovec[iovcnt].len = SCTP_BUF_LEN(m);
   2858 		send_count += send_iovec[iovcnt].len;
   2859 #endif
   2860 	}
   2861 
   2862 	if (m != NULL) {
   2863 		SCTP_PRINTF("mbuf chain couldn't be copied completely\n");
   2864 		goto free_mbuf;
   2865 	}
   2866 
   2867 #if !defined (__Userspace_os_Windows)
   2868 	msg_hdr.msg_name = (struct sockaddr *) &dst;
   2869 	msg_hdr.msg_namelen = sizeof(struct sockaddr_in);
   2870 	msg_hdr.msg_iov = send_iovec;
   2871 	msg_hdr.msg_iovlen = iovcnt;
   2872 	msg_hdr.msg_control = NULL;
   2873 	msg_hdr.msg_controllen = 0;
   2874 	msg_hdr.msg_flags = 0;
   2875 
   2876 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
   2877 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   2878 			*result = errno;
   2879 		}
   2880 	}
   2881 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
   2882 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   2883 			*result = errno;
   2884 		}
   2885 	}
   2886 #else
   2887 	win_msg_hdr.name = (struct sockaddr *) &dst;
   2888 	win_msg_hdr.namelen = sizeof(struct sockaddr_in);
   2889 	win_msg_hdr.lpBuffers = (LPWSABUF)send_iovec;
   2890 	win_msg_hdr.dwBufferCount = iovcnt;
   2891 	winbuf.len = 0;
   2892 	winbuf.buf = NULL;
   2893 	win_msg_hdr.Control = winbuf;
   2894 	win_msg_hdr.dwFlags = 0;
   2895 
   2896 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
   2897 		if (WSASendTo(SCTP_BASE_VAR(userspace_rawsctp), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   2898 			*result = WSAGetLastError();
   2899 		} else if (win_sent_len != send_len) {
   2900 			*result = WSAGetLastError();
   2901 		}
   2902 	}
   2903 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
   2904 		if (WSASendTo(SCTP_BASE_VAR(userspace_udpsctp), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   2905 			*result = WSAGetLastError();
   2906 		} else if (win_sent_len != send_len) {
   2907 			*result = WSAGetLastError();
   2908 		}
   2909 	}
   2910 #endif
   2911 free_mbuf:
   2912 	sctp_m_freem(m_orig);
   2913 }
   2914 #endif
   2915 
   2916 #if defined (INET6)
   2917 void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
   2918                                             struct route_in6 *ro, void *stcb,
   2919                                             uint32_t vrf_id)
   2920 {
   2921 	struct mbuf *m;
   2922 	struct mbuf *m_orig;
   2923 	int iovcnt;
   2924 	int send_len;
   2925 	int len;
   2926 	int send_count;
   2927 	struct ip6_hdr *ip6;
   2928 	struct udphdr *udp;
   2929 #if !defined (__Userspace_os_Windows)
   2930 	int res;
   2931 #endif
   2932 	struct sockaddr_in6 dst;
   2933 #if defined (__Userspace_os_Windows)
   2934 	WSAMSG win_msg_hdr;
   2935 	int win_sent_len;
   2936 	WSABUF send_iovec[MAXLEN_MBUF_CHAIN];
   2937 	WSABUF winbuf;
   2938 #else
   2939 	struct iovec send_iovec[MAXLEN_MBUF_CHAIN];
   2940 	struct msghdr msg_hdr;
   2941 #endif
   2942 	int use_udp_tunneling;
   2943 
   2944 	*result = 0;
   2945 
   2946 	m = SCTP_HEADER_TO_CHAIN(o_pak);
   2947 	m_orig = m;
   2948 
   2949 	len = sizeof(struct ip6_hdr);
   2950 
   2951 	if (SCTP_BUF_LEN(m) < len) {
   2952 		if ((m = m_pullup(m, len)) == 0) {
   2953 			SCTP_PRINTF("Can not get the IP header in the first mbuf.\n");
   2954 			return;
   2955 		}
   2956 	}
   2957 
   2958 	ip6 = mtod(m, struct ip6_hdr *);
   2959 	use_udp_tunneling = (ip6->ip6_nxt == IPPROTO_UDP);
   2960 
   2961 	if (use_udp_tunneling) {
   2962 		len = sizeof(struct ip6_hdr) + sizeof(struct udphdr);
   2963 		if (SCTP_BUF_LEN(m) < len) {
   2964 			if ((m = m_pullup(m, len)) == 0) {
   2965 				SCTP_PRINTF("Can not get the UDP/IP header in the first mbuf.\n");
   2966 				return;
   2967 			}
   2968 			ip6 = mtod(m, struct ip6_hdr *);
   2969 		}
   2970 		udp = (struct udphdr *)(ip6 + 1);
   2971 	} else {
   2972 		udp = NULL;
   2973 	}
   2974 
   2975 	if (!use_udp_tunneling) {
   2976 		if (ip6->ip6_src.s6_addr == in6addr_any.s6_addr) {
   2977 			/* TODO get addr of outgoing interface */
   2978 			SCTP_PRINTF("Why did the SCTP implementation did not choose a source address?\n");
   2979 		}
   2980 		/* TODO need to worry about ro->ro_dst as in ip_output? */
   2981 #if defined(__Userspace_os_Linux) || defined (__Userspace_os_Windows)
   2982 		/* need to put certain fields into network order for Linux */
   2983 		ip6->ip6_plen = htons(ip6->ip6_plen);
   2984 #endif
   2985 	}
   2986 
   2987 	memset((void *)&dst, 0, sizeof(struct sockaddr_in6));
   2988 	dst.sin6_family = AF_INET6;
   2989 	dst.sin6_addr = ip6->ip6_dst;
   2990 #ifdef HAVE_SIN6_LEN
   2991 	dst.sin6_len = sizeof(struct sockaddr_in6);
   2992 #endif
   2993 
   2994 	if (use_udp_tunneling) {
   2995 		dst.sin6_port = udp->uh_dport;
   2996 	} else {
   2997 		dst.sin6_port = 0;
   2998 	}
   2999 
   3000 	/* tweak the mbuf chain */
   3001 	if (use_udp_tunneling) {
   3002 		m_adj(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
   3003 	} else {
   3004 	  m_adj(m, sizeof(struct ip6_hdr));
   3005 	}
   3006 
   3007 	send_len = SCTP_HEADER_LEN(m); /* length of entire packet */
   3008 	send_count = 0;
   3009 	for (iovcnt = 0; m != NULL && iovcnt < MAXLEN_MBUF_CHAIN; m = m->m_next, iovcnt++) {
   3010 #if !defined (__Userspace_os_Windows)
   3011 		send_iovec[iovcnt].iov_base = (caddr_t)m->m_data;
   3012 		send_iovec[iovcnt].iov_len = SCTP_BUF_LEN(m);
   3013 		send_count += send_iovec[iovcnt].iov_len;
   3014 #else
   3015 		send_iovec[iovcnt].buf = (caddr_t)m->m_data;
   3016 		send_iovec[iovcnt].len = SCTP_BUF_LEN(m);
   3017 		send_count += send_iovec[iovcnt].len;
   3018 #endif
   3019 	}
   3020 	if (m != NULL) {
   3021 		SCTP_PRINTF("mbuf chain couldn't be copied completely\n");
   3022 		goto free_mbuf;
   3023 	}
   3024 
   3025 #if !defined (__Userspace_os_Windows)
   3026 	msg_hdr.msg_name = (struct sockaddr *) &dst;
   3027 	msg_hdr.msg_namelen = sizeof(struct sockaddr_in6);
   3028 	msg_hdr.msg_iov = send_iovec;
   3029 	msg_hdr.msg_iovlen = iovcnt;
   3030 	msg_hdr.msg_control = NULL;
   3031 	msg_hdr.msg_controllen = 0;
   3032 	msg_hdr.msg_flags = 0;
   3033 
   3034 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
   3035 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   3036 			*result = errno;
   3037 		}
   3038 	}
   3039 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
   3040 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   3041 			*result = errno;
   3042 		}
   3043 	}
   3044 #else
   3045 	win_msg_hdr.name = (struct sockaddr *) &dst;
   3046 	win_msg_hdr.namelen = sizeof(struct sockaddr_in6);
   3047 	win_msg_hdr.lpBuffers = (LPWSABUF)send_iovec;
   3048 	win_msg_hdr.dwBufferCount = iovcnt;
   3049 	winbuf.len = 0;
   3050 	winbuf.buf = NULL;
   3051 	win_msg_hdr.Control = winbuf;
   3052 	win_msg_hdr.dwFlags = 0;
   3053 
   3054 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
   3055 		if (WSASendTo(SCTP_BASE_VAR(userspace_rawsctp6), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   3056 			*result = WSAGetLastError();
   3057 		} else if (win_sent_len != send_len) {
   3058 			*result = WSAGetLastError();
   3059 		}
   3060 	}
   3061 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
   3062 		if (WSASendTo(SCTP_BASE_VAR(userspace_udpsctp6), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   3063 			*result = WSAGetLastError();
   3064 		} else if (win_sent_len != send_len) {
   3065 			*result = WSAGetLastError();
   3066 		}
   3067 	}
   3068 #endif
   3069 free_mbuf:
   3070 	sctp_m_freem(m_orig);
   3071 }
   3072 #endif
   3073 
   3074 void
   3075 usrsctp_register_address(void *addr)
   3076 {
   3077 	struct sockaddr_conn sconn;
   3078 
   3079 	memset(&sconn, 0, sizeof(struct sockaddr_conn));
   3080 	sconn.sconn_family = AF_CONN;
   3081 #ifdef HAVE_SCONN_LEN
   3082 	sconn.sconn_len = sizeof(struct sockaddr_conn);
   3083 #endif
   3084 	sconn.sconn_port = 0;
   3085 	sconn.sconn_addr = addr;
   3086 	sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID,
   3087 	                     NULL,
   3088 	                     0xffffffff,
   3089 	                     0,
   3090 	                     "conn",
   3091 	                     NULL,
   3092 	                     (struct sockaddr *)&sconn,
   3093 	                     0,
   3094 	                     0);
   3095 }
   3096 
   3097 void
   3098 usrsctp_deregister_address(void *addr)
   3099 {
   3100 	struct sockaddr_conn sconn;
   3101 
   3102 	memset(&sconn, 0, sizeof(struct sockaddr_conn));
   3103 	sconn.sconn_family = AF_CONN;
   3104 #ifdef HAVE_SCONN_LEN
   3105 	sconn.sconn_len = sizeof(struct sockaddr_conn);
   3106 #endif
   3107 	sconn.sconn_port = 0;
   3108 	sconn.sconn_addr = addr;
   3109 	sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID,
   3110 	                       (struct sockaddr *)&sconn,
   3111 	                       0xffffffff,
   3112 	                       "conn");
   3113 }
   3114 
   3115 #define PREAMBLE_FORMAT "\n%c %02d:%02d:%02d.%06ld "
   3116 #define PREAMBLE_LENGTH 19
   3117 #define HEADER "0000 "
   3118 #define TRAILER "# SCTP_PACKET\n"
   3119 
   3120 char *
   3121 usrsctp_dumppacket(void *buf, size_t len, int outbound)
   3122 {
   3123 	size_t i, pos;
   3124 	char *dump_buf, *packet;
   3125 #ifdef _WIN32
   3126 	struct timeb tb;
   3127 	struct tm t;
   3128 #else
   3129 	struct timeval tv;
   3130 	struct tm *t;
   3131 	time_t sec;
   3132 #endif
   3133 
   3134 	if ((len == 0) || (buf == NULL)) {
   3135 		return (NULL);
   3136 	}
   3137 	if ((dump_buf = malloc(PREAMBLE_LENGTH + strlen(HEADER) + 3 * len + strlen(TRAILER) + 1)) == NULL) {
   3138 		return (NULL);
   3139 	}
   3140 	pos = 0;
   3141 #ifdef _WIN32
   3142 	ftime(&tb);
   3143 	localtime_s(&t, &tb.time);
   3144 	_snprintf_s(dump_buf, PREAMBLE_LENGTH + 1, PREAMBLE_LENGTH, PREAMBLE_FORMAT,
   3145 	            outbound ? 'O' : 'I',
   3146 	            t.tm_hour, t.tm_min, t.tm_sec, (long)(1000 * tb.millitm));
   3147 #else
   3148 	gettimeofday(&tv, NULL);
   3149 	sec = (time_t)tv.tv_sec;
   3150 	t = localtime((const time_t *)&sec);
   3151 	snprintf(dump_buf, PREAMBLE_LENGTH + 1, PREAMBLE_FORMAT,
   3152 	         outbound ? 'O' : 'I',
   3153 	         t->tm_hour, t->tm_min, t->tm_sec, (long)tv.tv_usec);
   3154 #endif
   3155 	pos += PREAMBLE_LENGTH;
   3156 #ifdef _WIN32
   3157 	strncpy_s(dump_buf + pos, strlen(HEADER) + 1, HEADER, strlen(HEADER));
   3158 #else
   3159 	strcpy(dump_buf + pos, HEADER);
   3160 #endif
   3161 	pos += strlen(HEADER);
   3162 	packet = (char *)buf;
   3163 	for (i = 0; i < len; i++) {
   3164 		uint8_t byte, low, high;
   3165 
   3166 		byte = (uint8_t)packet[i];
   3167 		high = byte / 16;
   3168 		low = byte % 16;
   3169 		dump_buf[pos++] = high < 10 ? '0' + high : 'a' + (high - 10);
   3170 		dump_buf[pos++] = low < 10 ? '0' + low : 'a' + (low - 10);
   3171 		dump_buf[pos++] = ' ';
   3172 	}
   3173 #ifdef _WIN32
   3174 	strncpy_s(dump_buf + pos, strlen(TRAILER) + 1, TRAILER, strlen(TRAILER));
   3175 #else
   3176 	strcpy(dump_buf + pos, TRAILER);
   3177 #endif
   3178 	pos += strlen(TRAILER);
   3179 	dump_buf[pos++] = '\0';
   3180 	return (dump_buf);
   3181 }
   3182 
   3183 void
   3184 usrsctp_freedumpbuffer(char *buf)
   3185 {
   3186 	free(buf);
   3187 }
   3188 
   3189 void
   3190 usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bits)
   3191 {
   3192 	struct sockaddr_conn src, dst;
   3193 	struct mbuf *m;
   3194 	struct sctphdr *sh;
   3195 	struct sctp_chunkhdr *ch;
   3196 
   3197 	SCTP_STAT_INCR(sctps_recvpackets);
   3198 	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
   3199 	memset(&src, 0, sizeof(struct sockaddr_conn));
   3200 	src.sconn_family = AF_CONN;
   3201 #ifdef HAVE_SCONN_LEN
   3202 	src.sconn_len = sizeof(struct sockaddr_conn);
   3203 #endif
   3204 	src.sconn_addr = addr;
   3205 	memset(&dst, 0, sizeof(struct sockaddr_conn));
   3206 	dst.sconn_family = AF_CONN;
   3207 #ifdef HAVE_SCONN_LEN
   3208 	dst.sconn_len = sizeof(struct sockaddr_conn);
   3209 #endif
   3210 	dst.sconn_addr = addr;
   3211 	if ((m = sctp_get_mbuf_for_msg(length, 1, M_NOWAIT, 0, MT_DATA)) == NULL) {
   3212 		return;
   3213 	}
   3214 	m_copyback(m, 0, length, (caddr_t)buffer);
   3215 	if (SCTP_BUF_LEN(m) < (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) {
   3216 		if ((m = m_pullup(m, sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) == NULL) {
   3217 			SCTP_STAT_INCR(sctps_hdrops);
   3218 			return;
   3219 		}
   3220 	}
   3221 	sh = mtod(m, struct sctphdr *);;
   3222 	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
   3223 	src.sconn_port = sh->src_port;
   3224 	dst.sconn_port = sh->dest_port;
   3225 	sctp_common_input_processing(&m, 0, sizeof(struct sctphdr), length,
   3226 	                             (struct sockaddr *)&src,
   3227 	                             (struct sockaddr *)&dst,
   3228 	                             sh, ch,
   3229 #if !defined(SCTP_WITH_NO_CSUM)
   3230 	                             1,
   3231 #endif
   3232 	                             ecn_bits,
   3233 	                             SCTP_DEFAULT_VRFID, 0);
   3234 	if (m) {
   3235 		sctp_m_freem(m);
   3236 	}
   3237 	return;
   3238 }
   3239 
   3240 
   3241 #define USRSCTP_SYSCTL_SET_DEF(__field) \
   3242 void usrsctp_sysctl_set_ ## __field(uint32_t value) { \
   3243 	SCTP_BASE_SYSCTL(__field) = value; \
   3244 }
   3245 
   3246 USRSCTP_SYSCTL_SET_DEF(sctp_sendspace)
   3247 USRSCTP_SYSCTL_SET_DEF(sctp_recvspace)
   3248 USRSCTP_SYSCTL_SET_DEF(sctp_auto_asconf)
   3249 USRSCTP_SYSCTL_SET_DEF(sctp_multiple_asconfs)
   3250 USRSCTP_SYSCTL_SET_DEF(sctp_ecn_enable)
   3251 USRSCTP_SYSCTL_SET_DEF(sctp_pr_enable)
   3252 USRSCTP_SYSCTL_SET_DEF(sctp_auth_enable)
   3253 USRSCTP_SYSCTL_SET_DEF(sctp_asconf_enable)
   3254 USRSCTP_SYSCTL_SET_DEF(sctp_reconfig_enable)
   3255 USRSCTP_SYSCTL_SET_DEF(sctp_nrsack_enable)
   3256 USRSCTP_SYSCTL_SET_DEF(sctp_pktdrop_enable)
   3257 USRSCTP_SYSCTL_SET_DEF(sctp_strict_sacks)
   3258 #if !defined(SCTP_WITH_NO_CSUM)
   3259 USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback)
   3260 #endif
   3261 USRSCTP_SYSCTL_SET_DEF(sctp_peer_chunk_oh)
   3262 USRSCTP_SYSCTL_SET_DEF(sctp_max_burst_default)
   3263 USRSCTP_SYSCTL_SET_DEF(sctp_max_chunks_on_queue)
   3264 USRSCTP_SYSCTL_SET_DEF(sctp_hashtblsize)
   3265 USRSCTP_SYSCTL_SET_DEF(sctp_pcbtblsize)
   3266 USRSCTP_SYSCTL_SET_DEF(sctp_min_split_point)
   3267 USRSCTP_SYSCTL_SET_DEF(sctp_chunkscale)
   3268 USRSCTP_SYSCTL_SET_DEF(sctp_delayed_sack_time_default)
   3269 USRSCTP_SYSCTL_SET_DEF(sctp_sack_freq_default)
   3270 USRSCTP_SYSCTL_SET_DEF(sctp_system_free_resc_limit)
   3271 USRSCTP_SYSCTL_SET_DEF(sctp_asoc_free_resc_limit)
   3272 USRSCTP_SYSCTL_SET_DEF(sctp_heartbeat_interval_default)
   3273 USRSCTP_SYSCTL_SET_DEF(sctp_pmtu_raise_time_default)
   3274 USRSCTP_SYSCTL_SET_DEF(sctp_shutdown_guard_time_default)
   3275 USRSCTP_SYSCTL_SET_DEF(sctp_secret_lifetime_default)
   3276 USRSCTP_SYSCTL_SET_DEF(sctp_rto_max_default)
   3277 USRSCTP_SYSCTL_SET_DEF(sctp_rto_min_default)
   3278 USRSCTP_SYSCTL_SET_DEF(sctp_rto_initial_default)
   3279 USRSCTP_SYSCTL_SET_DEF(sctp_init_rto_max_default)
   3280 USRSCTP_SYSCTL_SET_DEF(sctp_valid_cookie_life_default)
   3281 USRSCTP_SYSCTL_SET_DEF(sctp_init_rtx_max_default)
   3282 USRSCTP_SYSCTL_SET_DEF(sctp_assoc_rtx_max_default)
   3283 USRSCTP_SYSCTL_SET_DEF(sctp_path_rtx_max_default)
   3284 USRSCTP_SYSCTL_SET_DEF(sctp_add_more_threshold)
   3285 USRSCTP_SYSCTL_SET_DEF(sctp_nr_outgoing_streams_default)
   3286 USRSCTP_SYSCTL_SET_DEF(sctp_cmt_on_off)
   3287 USRSCTP_SYSCTL_SET_DEF(sctp_cmt_use_dac)
   3288 USRSCTP_SYSCTL_SET_DEF(sctp_use_cwnd_based_maxburst)
   3289 USRSCTP_SYSCTL_SET_DEF(sctp_nat_friendly)
   3290 USRSCTP_SYSCTL_SET_DEF(sctp_L2_abc_variable)
   3291 USRSCTP_SYSCTL_SET_DEF(sctp_mbuf_threshold_count)
   3292 USRSCTP_SYSCTL_SET_DEF(sctp_do_drain)
   3293 USRSCTP_SYSCTL_SET_DEF(sctp_hb_maxburst)
   3294 USRSCTP_SYSCTL_SET_DEF(sctp_abort_if_one_2_one_hits_limit)
   3295 USRSCTP_SYSCTL_SET_DEF(sctp_strict_data_order)
   3296 USRSCTP_SYSCTL_SET_DEF(sctp_min_residual)
   3297 USRSCTP_SYSCTL_SET_DEF(sctp_max_retran_chunk)
   3298 USRSCTP_SYSCTL_SET_DEF(sctp_logging_level)
   3299 USRSCTP_SYSCTL_SET_DEF(sctp_default_cc_module)
   3300 USRSCTP_SYSCTL_SET_DEF(sctp_default_frag_interleave)
   3301 USRSCTP_SYSCTL_SET_DEF(sctp_mobility_base)
   3302 USRSCTP_SYSCTL_SET_DEF(sctp_mobility_fasthandoff)
   3303 USRSCTP_SYSCTL_SET_DEF(sctp_inits_include_nat_friendly)
   3304 USRSCTP_SYSCTL_SET_DEF(sctp_udp_tunneling_port)
   3305 USRSCTP_SYSCTL_SET_DEF(sctp_enable_sack_immediately)
   3306 USRSCTP_SYSCTL_SET_DEF(sctp_vtag_time_wait)
   3307 USRSCTP_SYSCTL_SET_DEF(sctp_blackhole)
   3308 USRSCTP_SYSCTL_SET_DEF(sctp_diag_info_code)
   3309 USRSCTP_SYSCTL_SET_DEF(sctp_fr_max_burst_default)
   3310 USRSCTP_SYSCTL_SET_DEF(sctp_path_pf_threshold)
   3311 USRSCTP_SYSCTL_SET_DEF(sctp_default_ss_module)
   3312 USRSCTP_SYSCTL_SET_DEF(sctp_rttvar_bw)
   3313 USRSCTP_SYSCTL_SET_DEF(sctp_rttvar_rtt)
   3314 USRSCTP_SYSCTL_SET_DEF(sctp_rttvar_eqret)
   3315 USRSCTP_SYSCTL_SET_DEF(sctp_steady_step)
   3316 USRSCTP_SYSCTL_SET_DEF(sctp_use_dccc_ecn)
   3317 USRSCTP_SYSCTL_SET_DEF(sctp_buffer_splitting)
   3318 USRSCTP_SYSCTL_SET_DEF(sctp_initial_cwnd)
   3319 #ifdef SCTP_DEBUG
   3320 USRSCTP_SYSCTL_SET_DEF(sctp_debug_on)
   3321 #endif
   3322 
   3323 #define USRSCTP_SYSCTL_GET_DEF(__field) \
   3324 uint32_t usrsctp_sysctl_get_ ## __field(void) { \
   3325 	return SCTP_BASE_SYSCTL(__field); \
   3326 }
   3327 
   3328 USRSCTP_SYSCTL_GET_DEF(sctp_sendspace)
   3329 USRSCTP_SYSCTL_GET_DEF(sctp_recvspace)
   3330 USRSCTP_SYSCTL_GET_DEF(sctp_auto_asconf)
   3331 USRSCTP_SYSCTL_GET_DEF(sctp_multiple_asconfs)
   3332 USRSCTP_SYSCTL_GET_DEF(sctp_ecn_enable)
   3333 USRSCTP_SYSCTL_GET_DEF(sctp_pr_enable)
   3334 USRSCTP_SYSCTL_GET_DEF(sctp_auth_enable)
   3335 USRSCTP_SYSCTL_GET_DEF(sctp_asconf_enable)
   3336 USRSCTP_SYSCTL_GET_DEF(sctp_reconfig_enable)
   3337 USRSCTP_SYSCTL_GET_DEF(sctp_nrsack_enable)
   3338 USRSCTP_SYSCTL_GET_DEF(sctp_pktdrop_enable)
   3339 USRSCTP_SYSCTL_GET_DEF(sctp_strict_sacks)
   3340 #if !defined(SCTP_WITH_NO_CSUM)
   3341 USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback)
   3342 #endif
   3343 USRSCTP_SYSCTL_GET_DEF(sctp_peer_chunk_oh)
   3344 USRSCTP_SYSCTL_GET_DEF(sctp_max_burst_default)
   3345 USRSCTP_SYSCTL_GET_DEF(sctp_max_chunks_on_queue)
   3346 USRSCTP_SYSCTL_GET_DEF(sctp_hashtblsize)
   3347 USRSCTP_SYSCTL_GET_DEF(sctp_pcbtblsize)
   3348 USRSCTP_SYSCTL_GET_DEF(sctp_min_split_point)
   3349 USRSCTP_SYSCTL_GET_DEF(sctp_chunkscale)
   3350 USRSCTP_SYSCTL_GET_DEF(sctp_delayed_sack_time_default)
   3351 USRSCTP_SYSCTL_GET_DEF(sctp_sack_freq_default)
   3352 USRSCTP_SYSCTL_GET_DEF(sctp_system_free_resc_limit)
   3353 USRSCTP_SYSCTL_GET_DEF(sctp_asoc_free_resc_limit)
   3354 USRSCTP_SYSCTL_GET_DEF(sctp_heartbeat_interval_default)
   3355 USRSCTP_SYSCTL_GET_DEF(sctp_pmtu_raise_time_default)
   3356 USRSCTP_SYSCTL_GET_DEF(sctp_shutdown_guard_time_default)
   3357 USRSCTP_SYSCTL_GET_DEF(sctp_secret_lifetime_default)
   3358 USRSCTP_SYSCTL_GET_DEF(sctp_rto_max_default)
   3359 USRSCTP_SYSCTL_GET_DEF(sctp_rto_min_default)
   3360 USRSCTP_SYSCTL_GET_DEF(sctp_rto_initial_default)
   3361 USRSCTP_SYSCTL_GET_DEF(sctp_init_rto_max_default)
   3362 USRSCTP_SYSCTL_GET_DEF(sctp_valid_cookie_life_default)
   3363 USRSCTP_SYSCTL_GET_DEF(sctp_init_rtx_max_default)
   3364 USRSCTP_SYSCTL_GET_DEF(sctp_assoc_rtx_max_default)
   3365 USRSCTP_SYSCTL_GET_DEF(sctp_path_rtx_max_default)
   3366 USRSCTP_SYSCTL_GET_DEF(sctp_add_more_threshold)
   3367 USRSCTP_SYSCTL_GET_DEF(sctp_nr_outgoing_streams_default)
   3368 USRSCTP_SYSCTL_GET_DEF(sctp_cmt_on_off)
   3369 USRSCTP_SYSCTL_GET_DEF(sctp_cmt_use_dac)
   3370 USRSCTP_SYSCTL_GET_DEF(sctp_use_cwnd_based_maxburst)
   3371 USRSCTP_SYSCTL_GET_DEF(sctp_nat_friendly)
   3372 USRSCTP_SYSCTL_GET_DEF(sctp_L2_abc_variable)
   3373 USRSCTP_SYSCTL_GET_DEF(sctp_mbuf_threshold_count)
   3374 USRSCTP_SYSCTL_GET_DEF(sctp_do_drain)
   3375 USRSCTP_SYSCTL_GET_DEF(sctp_hb_maxburst)
   3376 USRSCTP_SYSCTL_GET_DEF(sctp_abort_if_one_2_one_hits_limit)
   3377 USRSCTP_SYSCTL_GET_DEF(sctp_strict_data_order)
   3378 USRSCTP_SYSCTL_GET_DEF(sctp_min_residual)
   3379 USRSCTP_SYSCTL_GET_DEF(sctp_max_retran_chunk)
   3380 USRSCTP_SYSCTL_GET_DEF(sctp_logging_level)
   3381 USRSCTP_SYSCTL_GET_DEF(sctp_default_cc_module)
   3382 USRSCTP_SYSCTL_GET_DEF(sctp_default_frag_interleave)
   3383 USRSCTP_SYSCTL_GET_DEF(sctp_mobility_base)
   3384 USRSCTP_SYSCTL_GET_DEF(sctp_mobility_fasthandoff)
   3385 USRSCTP_SYSCTL_GET_DEF(sctp_inits_include_nat_friendly)
   3386 USRSCTP_SYSCTL_GET_DEF(sctp_udp_tunneling_port)
   3387 USRSCTP_SYSCTL_GET_DEF(sctp_enable_sack_immediately)
   3388 USRSCTP_SYSCTL_GET_DEF(sctp_vtag_time_wait)
   3389 USRSCTP_SYSCTL_GET_DEF(sctp_blackhole)
   3390 USRSCTP_SYSCTL_GET_DEF(sctp_diag_info_code)
   3391 USRSCTP_SYSCTL_GET_DEF(sctp_fr_max_burst_default)
   3392 USRSCTP_SYSCTL_GET_DEF(sctp_path_pf_threshold)
   3393 USRSCTP_SYSCTL_GET_DEF(sctp_default_ss_module)
   3394 USRSCTP_SYSCTL_GET_DEF(sctp_rttvar_bw)
   3395 USRSCTP_SYSCTL_GET_DEF(sctp_rttvar_rtt)
   3396 USRSCTP_SYSCTL_GET_DEF(sctp_rttvar_eqret)
   3397 USRSCTP_SYSCTL_GET_DEF(sctp_steady_step)
   3398 USRSCTP_SYSCTL_GET_DEF(sctp_use_dccc_ecn)
   3399 USRSCTP_SYSCTL_GET_DEF(sctp_buffer_splitting)
   3400 USRSCTP_SYSCTL_GET_DEF(sctp_initial_cwnd)
   3401 #ifdef SCTP_DEBUG
   3402 USRSCTP_SYSCTL_GET_DEF(sctp_debug_on)
   3403 #endif
   3404 
   3405 void usrsctp_get_stat(struct sctpstat *stat)
   3406 {
   3407 	*stat = SCTP_BASE_STATS;
   3408 }
   3409