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