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