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