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