1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. 5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * a) Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 14 * b) Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the distribution. 17 * 18 * c) Neither the name of Cisco Systems, Inc. nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __FBSDID("$FreeBSD$"); 37 38 #include <netinet/sctp_os.h> 39 #include <sys/proc.h> 40 #include <netinet/sctp_pcb.h> 41 #include <netinet/sctp_header.h> 42 #include <netinet/sctp_var.h> 43 #ifdef INET6 44 #include <netinet6/sctp6_var.h> 45 #endif 46 #include <netinet/sctp_sysctl.h> 47 #include <netinet/sctp_output.h> 48 #include <netinet/sctp_uio.h> 49 #include <netinet/sctp_asconf.h> 50 #include <netinet/sctputil.h> 51 #include <netinet/sctp_indata.h> 52 #include <netinet/sctp_timer.h> 53 #include <netinet/sctp_auth.h> 54 #include <netinet/sctp_bsd_addr.h> 55 #include <netinet/udp.h> 56 #include <sys/eventhandler.h> 57 58 59 60 extern const struct sctp_cc_functions sctp_cc_functions[]; 61 extern const struct sctp_ss_functions sctp_ss_functions[]; 62 63 void 64 sctp_init(void) 65 { 66 u_long sb_max_adj; 67 68 /* Initialize and modify the sysctled variables */ 69 sctp_init_sysctls(); 70 if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE) 71 SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = (nmbclusters / 8); 72 /* 73 * Allow a user to take no more than 1/2 the number of clusters or 74 * the SB_MAX whichever is smaller for the send window. 75 */ 76 sb_max_adj = (u_long)((u_quad_t)(SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES)); 77 SCTP_BASE_SYSCTL(sctp_sendspace) = min(sb_max_adj, 78 (((uint32_t)nmbclusters / 2) * SCTP_DEFAULT_MAXSEGMENT)); 79 /* 80 * Now for the recv window, should we take the same amount? or 81 * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For 82 * now I will just copy. 83 */ 84 SCTP_BASE_SYSCTL(sctp_recvspace) = SCTP_BASE_SYSCTL(sctp_sendspace); 85 SCTP_BASE_VAR(first_time) = 0; 86 SCTP_BASE_VAR(sctp_pcb_initialized) = 0; 87 sctp_pcb_init(); 88 #if defined(SCTP_PACKET_LOGGING) 89 SCTP_BASE_VAR(packet_log_writers) = 0; 90 SCTP_BASE_VAR(packet_log_end) = 0; 91 memset(&SCTP_BASE_VAR(packet_log_buffer), 0, SCTP_PACKET_LOG_SIZE); 92 #endif 93 SCTP_BASE_VAR(eh_tag) = EVENTHANDLER_REGISTER(rt_addrmsg, 94 sctp_addr_change_event_handler, NULL, EVENTHANDLER_PRI_FIRST); 95 } 96 97 #ifdef VIMAGE 98 static void 99 sctp_finish(void *unused __unused) 100 { 101 sctp_pcb_finish(); 102 } 103 104 VNET_SYSUNINIT(sctp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, sctp_finish, NULL); 105 #endif 106 107 void 108 sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint16_t nxtsz) 109 { 110 struct sctp_tmit_chunk *chk; 111 uint16_t overhead; 112 113 /* Adjust that too */ 114 stcb->asoc.smallest_mtu = nxtsz; 115 /* now off to subtract IP_DF flag if needed */ 116 overhead = IP_HDR_SIZE + sizeof(struct sctphdr); 117 if (sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks)) { 118 overhead += sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id); 119 } 120 TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) { 121 if ((chk->send_size + overhead) > nxtsz) { 122 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 123 } 124 } 125 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 126 if ((chk->send_size + overhead) > nxtsz) { 127 /* 128 * For this guy we also mark for immediate resend 129 * since we sent to big of chunk 130 */ 131 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 132 if (chk->sent < SCTP_DATAGRAM_RESEND) { 133 sctp_flight_size_decrease(chk); 134 sctp_total_flight_decrease(stcb, chk); 135 chk->sent = SCTP_DATAGRAM_RESEND; 136 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 137 chk->rec.data.doing_fast_retransmit = 0; 138 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) { 139 sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU, 140 chk->whoTo->flight_size, 141 chk->book_size, 142 (uint32_t)(uintptr_t)chk->whoTo, 143 chk->rec.data.tsn); 144 } 145 /* Clear any time so NO RTT is being done */ 146 if (chk->do_rtt == 1) { 147 chk->do_rtt = 0; 148 chk->whoTo->rto_needed = 1; 149 } 150 } 151 } 152 } 153 } 154 155 #ifdef INET 156 void 157 sctp_notify(struct sctp_inpcb *inp, 158 struct sctp_tcb *stcb, 159 struct sctp_nets *net, 160 uint8_t icmp_type, 161 uint8_t icmp_code, 162 uint16_t ip_len, 163 uint32_t next_mtu) 164 { 165 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 166 struct socket *so; 167 #endif 168 int timer_stopped; 169 170 if (icmp_type != ICMP_UNREACH) { 171 /* We only care about unreachable */ 172 SCTP_TCB_UNLOCK(stcb); 173 return; 174 } 175 if ((icmp_code == ICMP_UNREACH_NET) || 176 (icmp_code == ICMP_UNREACH_HOST) || 177 (icmp_code == ICMP_UNREACH_NET_UNKNOWN) || 178 (icmp_code == ICMP_UNREACH_HOST_UNKNOWN) || 179 (icmp_code == ICMP_UNREACH_ISOLATED) || 180 (icmp_code == ICMP_UNREACH_NET_PROHIB) || 181 (icmp_code == ICMP_UNREACH_HOST_PROHIB) || 182 (icmp_code == ICMP_UNREACH_FILTER_PROHIB)) { 183 /* Mark the net unreachable. */ 184 if (net->dest_state & SCTP_ADDR_REACHABLE) { 185 /* OK, that destination is NOT reachable. */ 186 net->dest_state &= ~SCTP_ADDR_REACHABLE; 187 net->dest_state &= ~SCTP_ADDR_PF; 188 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 189 stcb, 0, 190 (void *)net, SCTP_SO_NOT_LOCKED); 191 } 192 SCTP_TCB_UNLOCK(stcb); 193 } else if ((icmp_code == ICMP_UNREACH_PROTOCOL) || 194 (icmp_code == ICMP_UNREACH_PORT)) { 195 /* Treat it like an ABORT. */ 196 sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED); 197 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 198 so = SCTP_INP_SO(inp); 199 atomic_add_int(&stcb->asoc.refcnt, 1); 200 SCTP_TCB_UNLOCK(stcb); 201 SCTP_SOCKET_LOCK(so, 1); 202 SCTP_TCB_LOCK(stcb); 203 atomic_subtract_int(&stcb->asoc.refcnt, 1); 204 #endif 205 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 206 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2); 207 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 208 SCTP_SOCKET_UNLOCK(so, 1); 209 /* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed. */ 210 #endif 211 /* no need to unlock here, since the TCB is gone */ 212 } else if (icmp_code == ICMP_UNREACH_NEEDFRAG) { 213 if (net->dest_state & SCTP_ADDR_NO_PMTUD) { 214 SCTP_TCB_UNLOCK(stcb); 215 return; 216 } 217 /* Find the next (smaller) MTU */ 218 if (next_mtu == 0) { 219 /* 220 * Old type router that does not tell us what the 221 * next MTU is. Rats we will have to guess (in a 222 * educated fashion of course). 223 */ 224 next_mtu = sctp_get_prev_mtu(ip_len); 225 } 226 /* Stop the PMTU timer. */ 227 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 228 timer_stopped = 1; 229 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 230 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1); 231 } else { 232 timer_stopped = 0; 233 } 234 /* Update the path MTU. */ 235 if (net->port) { 236 next_mtu -= sizeof(struct udphdr); 237 } 238 if (net->mtu > next_mtu) { 239 net->mtu = next_mtu; 240 if (net->port) { 241 sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr)); 242 } else { 243 sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu); 244 } 245 } 246 /* Update the association MTU */ 247 if (stcb->asoc.smallest_mtu > next_mtu) { 248 sctp_pathmtu_adjustment(stcb, next_mtu); 249 } 250 /* Finally, start the PMTU timer if it was running before. */ 251 if (timer_stopped) { 252 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 253 } 254 SCTP_TCB_UNLOCK(stcb); 255 } else { 256 SCTP_TCB_UNLOCK(stcb); 257 } 258 } 259 260 void 261 sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip) 262 { 263 struct ip *outer_ip; 264 struct ip *inner_ip; 265 struct sctphdr *sh; 266 struct icmp *icmp; 267 struct sctp_inpcb *inp; 268 struct sctp_tcb *stcb; 269 struct sctp_nets *net; 270 struct sctp_init_chunk *ch; 271 struct sockaddr_in src, dst; 272 273 if (sa->sa_family != AF_INET || 274 ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) { 275 return; 276 } 277 if (PRC_IS_REDIRECT(cmd)) { 278 vip = NULL; 279 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) { 280 return; 281 } 282 if (vip != NULL) { 283 inner_ip = (struct ip *)vip; 284 icmp = (struct icmp *)((caddr_t)inner_ip - 285 (sizeof(struct icmp) - sizeof(struct ip))); 286 outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip)); 287 sh = (struct sctphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2)); 288 memset(&src, 0, sizeof(struct sockaddr_in)); 289 src.sin_family = AF_INET; 290 src.sin_len = sizeof(struct sockaddr_in); 291 src.sin_port = sh->src_port; 292 src.sin_addr = inner_ip->ip_src; 293 memset(&dst, 0, sizeof(struct sockaddr_in)); 294 dst.sin_family = AF_INET; 295 dst.sin_len = sizeof(struct sockaddr_in); 296 dst.sin_port = sh->dest_port; 297 dst.sin_addr = inner_ip->ip_dst; 298 /* 299 * 'dst' holds the dest of the packet that failed to be 300 * sent. 'src' holds our local endpoint address. Thus we 301 * reverse the dst and the src in the lookup. 302 */ 303 inp = NULL; 304 net = NULL; 305 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst, 306 (struct sockaddr *)&src, 307 &inp, &net, 1, 308 SCTP_DEFAULT_VRFID); 309 if ((stcb != NULL) && 310 (net != NULL) && 311 (inp != NULL)) { 312 /* Check the verification tag */ 313 if (ntohl(sh->v_tag) != 0) { 314 /* 315 * This must be the verification tag used 316 * for sending out packets. We don't 317 * consider packets reflecting the 318 * verification tag. 319 */ 320 if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) { 321 SCTP_TCB_UNLOCK(stcb); 322 return; 323 } 324 } else { 325 if (ntohs(outer_ip->ip_len) >= 326 sizeof(struct ip) + 327 8 + (inner_ip->ip_hl << 2) + 20) { 328 /* 329 * In this case we can check if we 330 * got an INIT chunk and if the 331 * initiate tag matches. 332 */ 333 ch = (struct sctp_init_chunk *)(sh + 1); 334 if ((ch->ch.chunk_type != SCTP_INITIATION) || 335 (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) { 336 SCTP_TCB_UNLOCK(stcb); 337 return; 338 } 339 } else { 340 SCTP_TCB_UNLOCK(stcb); 341 return; 342 } 343 } 344 sctp_notify(inp, stcb, net, 345 icmp->icmp_type, 346 icmp->icmp_code, 347 ntohs(inner_ip->ip_len), 348 (uint32_t)ntohs(icmp->icmp_nextmtu)); 349 } else { 350 if ((stcb == NULL) && (inp != NULL)) { 351 /* reduce ref-count */ 352 SCTP_INP_WLOCK(inp); 353 SCTP_INP_DECR_REF(inp); 354 SCTP_INP_WUNLOCK(inp); 355 } 356 if (stcb) { 357 SCTP_TCB_UNLOCK(stcb); 358 } 359 } 360 } 361 return; 362 } 363 #endif 364 365 static int 366 sctp_getcred(SYSCTL_HANDLER_ARGS) 367 { 368 struct xucred xuc; 369 struct sockaddr_in addrs[2]; 370 struct sctp_inpcb *inp; 371 struct sctp_nets *net; 372 struct sctp_tcb *stcb; 373 int error; 374 uint32_t vrf_id; 375 376 /* FIX, for non-bsd is this right? */ 377 vrf_id = SCTP_DEFAULT_VRFID; 378 379 error = priv_check(req->td, PRIV_NETINET_GETCRED); 380 381 if (error) 382 return (error); 383 384 error = SYSCTL_IN(req, addrs, sizeof(addrs)); 385 if (error) 386 return (error); 387 388 stcb = sctp_findassociation_addr_sa(sintosa(&addrs[1]), 389 sintosa(&addrs[0]), 390 &inp, &net, 1, vrf_id); 391 if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) { 392 if ((inp != NULL) && (stcb == NULL)) { 393 /* reduce ref-count */ 394 SCTP_INP_WLOCK(inp); 395 SCTP_INP_DECR_REF(inp); 396 goto cred_can_cont; 397 } 398 399 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 400 error = ENOENT; 401 goto out; 402 } 403 SCTP_TCB_UNLOCK(stcb); 404 /* 405 * We use the write lock here, only since in the error leg we need 406 * it. If we used RLOCK, then we would have to 407 * wlock/decr/unlock/rlock. Which in theory could create a hole. 408 * Better to use higher wlock. 409 */ 410 SCTP_INP_WLOCK(inp); 411 cred_can_cont: 412 error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket); 413 if (error) { 414 SCTP_INP_WUNLOCK(inp); 415 goto out; 416 } 417 cru2x(inp->sctp_socket->so_cred, &xuc); 418 SCTP_INP_WUNLOCK(inp); 419 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 420 out: 421 return (error); 422 } 423 424 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, 425 CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 426 0, 0, sctp_getcred, "S,ucred", 427 "Get the ucred of a SCTP connection"); 428 429 430 #ifdef INET 431 static void 432 sctp_abort(struct socket *so) 433 { 434 struct epoch_tracker et; 435 struct sctp_inpcb *inp; 436 uint32_t flags; 437 438 inp = (struct sctp_inpcb *)so->so_pcb; 439 if (inp == NULL) { 440 return; 441 } 442 443 NET_EPOCH_ENTER(et); 444 sctp_must_try_again: 445 flags = inp->sctp_flags; 446 #ifdef SCTP_LOG_CLOSING 447 sctp_log_closing(inp, NULL, 17); 448 #endif 449 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 450 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 451 #ifdef SCTP_LOG_CLOSING 452 sctp_log_closing(inp, NULL, 16); 453 #endif 454 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 455 SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 456 SOCK_LOCK(so); 457 SCTP_SB_CLEAR(so->so_snd); 458 /* 459 * same for the rcv ones, they are only here for the 460 * accounting/select. 461 */ 462 SCTP_SB_CLEAR(so->so_rcv); 463 464 /* Now null out the reference, we are completely detached. */ 465 so->so_pcb = NULL; 466 SOCK_UNLOCK(so); 467 } else { 468 flags = inp->sctp_flags; 469 if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 470 goto sctp_must_try_again; 471 } 472 } 473 NET_EPOCH_EXIT(et); 474 return; 475 } 476 477 static int 478 sctp_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED) 479 { 480 struct sctp_inpcb *inp; 481 struct inpcb *ip_inp; 482 int error; 483 uint32_t vrf_id = SCTP_DEFAULT_VRFID; 484 485 inp = (struct sctp_inpcb *)so->so_pcb; 486 if (inp != NULL) { 487 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 488 return (EINVAL); 489 } 490 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 491 error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); 492 if (error) { 493 return (error); 494 } 495 } 496 error = sctp_inpcb_alloc(so, vrf_id); 497 if (error) { 498 return (error); 499 } 500 inp = (struct sctp_inpcb *)so->so_pcb; 501 SCTP_INP_WLOCK(inp); 502 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */ 503 ip_inp = &inp->ip_inp.inp; 504 ip_inp->inp_vflag |= INP_IPV4; 505 ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); 506 SCTP_INP_WUNLOCK(inp); 507 return (0); 508 } 509 510 static int 511 sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p) 512 { 513 struct sctp_inpcb *inp; 514 515 inp = (struct sctp_inpcb *)so->so_pcb; 516 if (inp == NULL) { 517 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 518 return (EINVAL); 519 } 520 if (addr != NULL) { 521 if ((addr->sa_family != AF_INET) || 522 (addr->sa_len != sizeof(struct sockaddr_in))) { 523 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 524 return (EINVAL); 525 } 526 } 527 return (sctp_inpcb_bind(so, addr, NULL, p)); 528 } 529 530 #endif 531 void 532 sctp_close(struct socket *so) 533 { 534 struct epoch_tracker et; 535 struct sctp_inpcb *inp; 536 uint32_t flags; 537 538 inp = (struct sctp_inpcb *)so->so_pcb; 539 if (inp == NULL) 540 return; 541 542 /* 543 * Inform all the lower layer assoc that we are done. 544 */ 545 NET_EPOCH_ENTER(et); 546 sctp_must_try_again: 547 flags = inp->sctp_flags; 548 #ifdef SCTP_LOG_CLOSING 549 sctp_log_closing(inp, NULL, 17); 550 #endif 551 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 552 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 553 if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) || 554 (so->so_rcv.sb_cc > 0)) { 555 #ifdef SCTP_LOG_CLOSING 556 sctp_log_closing(inp, NULL, 13); 557 #endif 558 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 559 SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 560 } else { 561 #ifdef SCTP_LOG_CLOSING 562 sctp_log_closing(inp, NULL, 14); 563 #endif 564 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE, 565 SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 566 } 567 /* 568 * The socket is now detached, no matter what the state of 569 * the SCTP association. 570 */ 571 SOCK_LOCK(so); 572 SCTP_SB_CLEAR(so->so_snd); 573 /* 574 * same for the rcv ones, they are only here for the 575 * accounting/select. 576 */ 577 SCTP_SB_CLEAR(so->so_rcv); 578 579 /* Now null out the reference, we are completely detached. */ 580 so->so_pcb = NULL; 581 SOCK_UNLOCK(so); 582 } else { 583 flags = inp->sctp_flags; 584 if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 585 goto sctp_must_try_again; 586 } 587 } 588 NET_EPOCH_EXIT(et); 589 return; 590 } 591 592 593 int 594 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 595 struct mbuf *control, struct thread *p); 596 597 598 int 599 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 600 struct mbuf *control, struct thread *p) 601 { 602 struct sctp_inpcb *inp; 603 int error; 604 605 inp = (struct sctp_inpcb *)so->so_pcb; 606 if (inp == NULL) { 607 if (control) { 608 sctp_m_freem(control); 609 control = NULL; 610 } 611 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 612 sctp_m_freem(m); 613 return (EINVAL); 614 } 615 /* Got to have an to address if we are NOT a connected socket */ 616 if ((addr == NULL) && 617 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) || 618 (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))) { 619 goto connected_type; 620 } else if (addr == NULL) { 621 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ); 622 error = EDESTADDRREQ; 623 sctp_m_freem(m); 624 if (control) { 625 sctp_m_freem(control); 626 control = NULL; 627 } 628 return (error); 629 } 630 #ifdef INET6 631 if (addr->sa_family != AF_INET) { 632 /* must be a v4 address! */ 633 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ); 634 sctp_m_freem(m); 635 if (control) { 636 sctp_m_freem(control); 637 control = NULL; 638 } 639 error = EDESTADDRREQ; 640 return (error); 641 } 642 #endif /* INET6 */ 643 connected_type: 644 /* now what about control */ 645 if (control) { 646 if (inp->control) { 647 sctp_m_freem(inp->control); 648 inp->control = NULL; 649 } 650 inp->control = control; 651 } 652 /* Place the data */ 653 if (inp->pkt) { 654 SCTP_BUF_NEXT(inp->pkt_last) = m; 655 inp->pkt_last = m; 656 } else { 657 inp->pkt_last = inp->pkt = m; 658 } 659 if ( 660 /* FreeBSD uses a flag passed */ 661 ((flags & PRUS_MORETOCOME) == 0) 662 ) { 663 /* 664 * note with the current version this code will only be used 665 * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for 666 * re-defining sosend to use the sctp_sosend. One can 667 * optionally switch back to this code (by changing back the 668 * definitions) but this is not advisable. This code is used 669 * by FreeBSD when sending a file with sendfile() though. 670 */ 671 struct epoch_tracker et; 672 int ret; 673 674 NET_EPOCH_ENTER(et); 675 ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags); 676 NET_EPOCH_EXIT(et); 677 inp->pkt = NULL; 678 inp->control = NULL; 679 return (ret); 680 } else { 681 return (0); 682 } 683 } 684 685 int 686 sctp_disconnect(struct socket *so) 687 { 688 struct sctp_inpcb *inp; 689 690 inp = (struct sctp_inpcb *)so->so_pcb; 691 if (inp == NULL) { 692 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 693 return (ENOTCONN); 694 } 695 SCTP_INP_RLOCK(inp); 696 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 697 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 698 if (LIST_EMPTY(&inp->sctp_asoc_list)) { 699 /* No connection */ 700 SCTP_INP_RUNLOCK(inp); 701 return (0); 702 } else { 703 struct epoch_tracker et; 704 struct sctp_association *asoc; 705 struct sctp_tcb *stcb; 706 707 stcb = LIST_FIRST(&inp->sctp_asoc_list); 708 if (stcb == NULL) { 709 SCTP_INP_RUNLOCK(inp); 710 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 711 return (EINVAL); 712 } 713 SCTP_TCB_LOCK(stcb); 714 asoc = &stcb->asoc; 715 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 716 /* We are about to be freed, out of here */ 717 SCTP_TCB_UNLOCK(stcb); 718 SCTP_INP_RUNLOCK(inp); 719 return (0); 720 } 721 NET_EPOCH_ENTER(et); 722 if (((so->so_options & SO_LINGER) && 723 (so->so_linger == 0)) || 724 (so->so_rcv.sb_cc > 0)) { 725 if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) { 726 /* Left with Data unread */ 727 struct mbuf *op_err; 728 729 op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); 730 sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED); 731 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 732 } 733 SCTP_INP_RUNLOCK(inp); 734 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) || 735 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 736 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 737 } 738 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 739 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3); 740 /* No unlock tcb assoc is gone */ 741 NET_EPOCH_EXIT(et); 742 return (0); 743 } 744 if (TAILQ_EMPTY(&asoc->send_queue) && 745 TAILQ_EMPTY(&asoc->sent_queue) && 746 (asoc->stream_queue_cnt == 0)) { 747 /* there is nothing queued to send, so done */ 748 if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) { 749 goto abort_anyway; 750 } 751 if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) && 752 (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) { 753 /* only send SHUTDOWN 1st time thru */ 754 struct sctp_nets *netp; 755 756 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) || 757 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 758 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 759 } 760 SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); 761 sctp_stop_timers_for_shutdown(stcb); 762 if (stcb->asoc.alternate) { 763 netp = stcb->asoc.alternate; 764 } else { 765 netp = stcb->asoc.primary_destination; 766 } 767 sctp_send_shutdown(stcb, netp); 768 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 769 stcb->sctp_ep, stcb, netp); 770 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 771 stcb->sctp_ep, stcb, NULL); 772 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED); 773 } 774 } else { 775 /* 776 * we still got (or just got) data to send, 777 * so set SHUTDOWN_PENDING 778 */ 779 /* 780 * XXX sockets draft says that SCTP_EOF 781 * should be sent with no data. currently, 782 * we will allow user data to be sent first 783 * and move to SHUTDOWN-PENDING 784 */ 785 SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); 786 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL); 787 if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) { 788 SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT); 789 } 790 if (TAILQ_EMPTY(&asoc->send_queue) && 791 TAILQ_EMPTY(&asoc->sent_queue) && 792 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 793 struct mbuf *op_err; 794 795 abort_anyway: 796 op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); 797 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4; 798 sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED); 799 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 800 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) || 801 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 802 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 803 } 804 SCTP_INP_RUNLOCK(inp); 805 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 806 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5); 807 NET_EPOCH_EXIT(et); 808 return (0); 809 } else { 810 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED); 811 } 812 } 813 soisdisconnecting(so); 814 NET_EPOCH_EXIT(et); 815 SCTP_TCB_UNLOCK(stcb); 816 SCTP_INP_RUNLOCK(inp); 817 return (0); 818 } 819 /* not reached */ 820 } else { 821 /* UDP model does not support this */ 822 SCTP_INP_RUNLOCK(inp); 823 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 824 return (EOPNOTSUPP); 825 } 826 } 827 828 int 829 sctp_flush(struct socket *so, int how) 830 { 831 /* 832 * We will just clear out the values and let subsequent close clear 833 * out the data, if any. Note if the user did a shutdown(SHUT_RD) 834 * they will not be able to read the data, the socket will block 835 * that from happening. 836 */ 837 struct sctp_inpcb *inp; 838 839 inp = (struct sctp_inpcb *)so->so_pcb; 840 if (inp == NULL) { 841 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 842 return (EINVAL); 843 } 844 SCTP_INP_RLOCK(inp); 845 /* For the 1 to many model this does nothing */ 846 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 847 SCTP_INP_RUNLOCK(inp); 848 return (0); 849 } 850 SCTP_INP_RUNLOCK(inp); 851 if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) { 852 /* 853 * First make sure the sb will be happy, we don't use these 854 * except maybe the count 855 */ 856 SCTP_INP_WLOCK(inp); 857 SCTP_INP_READ_LOCK(inp); 858 inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ; 859 SCTP_INP_READ_UNLOCK(inp); 860 SCTP_INP_WUNLOCK(inp); 861 so->so_rcv.sb_cc = 0; 862 so->so_rcv.sb_mbcnt = 0; 863 so->so_rcv.sb_mb = NULL; 864 } 865 if ((how == PRU_FLUSH_WR) || (how == PRU_FLUSH_RDWR)) { 866 /* 867 * First make sure the sb will be happy, we don't use these 868 * except maybe the count 869 */ 870 so->so_snd.sb_cc = 0; 871 so->so_snd.sb_mbcnt = 0; 872 so->so_snd.sb_mb = NULL; 873 874 } 875 return (0); 876 } 877 878 int 879 sctp_shutdown(struct socket *so) 880 { 881 struct sctp_inpcb *inp; 882 883 inp = (struct sctp_inpcb *)so->so_pcb; 884 if (inp == NULL) { 885 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 886 return (EINVAL); 887 } 888 SCTP_INP_RLOCK(inp); 889 /* For UDP model this is a invalid call */ 890 if (!((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 891 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { 892 /* Restore the flags that the soshutdown took away. */ 893 SOCKBUF_LOCK(&so->so_rcv); 894 so->so_rcv.sb_state &= ~SBS_CANTRCVMORE; 895 SOCKBUF_UNLOCK(&so->so_rcv); 896 /* This proc will wakeup for read and do nothing (I hope) */ 897 SCTP_INP_RUNLOCK(inp); 898 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 899 return (EOPNOTSUPP); 900 } else { 901 /* 902 * Ok, if we reach here its the TCP model and it is either a 903 * SHUT_WR or SHUT_RDWR. This means we put the shutdown flag 904 * against it. 905 */ 906 struct epoch_tracker et; 907 struct sctp_tcb *stcb; 908 struct sctp_association *asoc; 909 struct sctp_nets *netp; 910 911 if ((so->so_state & 912 (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) { 913 SCTP_INP_RUNLOCK(inp); 914 return (ENOTCONN); 915 } 916 socantsendmore(so); 917 918 stcb = LIST_FIRST(&inp->sctp_asoc_list); 919 if (stcb == NULL) { 920 /* 921 * Ok, we hit the case that the shutdown call was 922 * made after an abort or something. Nothing to do 923 * now. 924 */ 925 SCTP_INP_RUNLOCK(inp); 926 return (0); 927 } 928 SCTP_TCB_LOCK(stcb); 929 asoc = &stcb->asoc; 930 if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) { 931 SCTP_TCB_UNLOCK(stcb); 932 SCTP_INP_RUNLOCK(inp); 933 return (0); 934 } 935 if ((SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) && 936 (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_ECHOED) && 937 (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN)) { 938 /* 939 * If we are not in or before ESTABLISHED, there is 940 * no protocol action required. 941 */ 942 SCTP_TCB_UNLOCK(stcb); 943 SCTP_INP_RUNLOCK(inp); 944 return (0); 945 } 946 NET_EPOCH_ENTER(et); 947 if (stcb->asoc.alternate) { 948 netp = stcb->asoc.alternate; 949 } else { 950 netp = stcb->asoc.primary_destination; 951 } 952 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) && 953 TAILQ_EMPTY(&asoc->send_queue) && 954 TAILQ_EMPTY(&asoc->sent_queue) && 955 (asoc->stream_queue_cnt == 0)) { 956 if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) { 957 goto abort_anyway; 958 } 959 /* there is nothing queued to send, so I'm done... */ 960 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 961 SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); 962 sctp_stop_timers_for_shutdown(stcb); 963 sctp_send_shutdown(stcb, netp); 964 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 965 stcb->sctp_ep, stcb, netp); 966 } else { 967 /* 968 * We still got (or just got) data to send, so set 969 * SHUTDOWN_PENDING. 970 */ 971 SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); 972 if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) { 973 SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT); 974 } 975 if (TAILQ_EMPTY(&asoc->send_queue) && 976 TAILQ_EMPTY(&asoc->sent_queue) && 977 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 978 struct mbuf *op_err; 979 980 abort_anyway: 981 op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); 982 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6; 983 SCTP_INP_RUNLOCK(inp); 984 sctp_abort_an_association(stcb->sctp_ep, stcb, 985 op_err, SCTP_SO_LOCKED); 986 NET_EPOCH_EXIT(et); 987 return (0); 988 } 989 } 990 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL); 991 /* 992 * XXX: Why do this in the case where we have still data 993 * queued? 994 */ 995 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED); 996 SCTP_TCB_UNLOCK(stcb); 997 SCTP_INP_RUNLOCK(inp); 998 NET_EPOCH_EXIT(et); 999 return (0); 1000 } 1001 } 1002 1003 /* 1004 * copies a "user" presentable address and removes embedded scope, etc. 1005 * returns 0 on success, 1 on error 1006 */ 1007 static uint32_t 1008 sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa) 1009 { 1010 #ifdef INET6 1011 struct sockaddr_in6 lsa6; 1012 1013 sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa, 1014 &lsa6); 1015 #endif 1016 memcpy(ss, sa, sa->sa_len); 1017 return (0); 1018 } 1019 1020 1021 1022 /* 1023 * NOTE: assumes addr lock is held 1024 */ 1025 static size_t 1026 sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, 1027 struct sctp_tcb *stcb, 1028 size_t limit, 1029 struct sockaddr_storage *sas, 1030 uint32_t vrf_id) 1031 { 1032 struct sctp_ifn *sctp_ifn; 1033 struct sctp_ifa *sctp_ifa; 1034 size_t actual; 1035 int loopback_scope; 1036 #if defined(INET) 1037 int ipv4_local_scope, ipv4_addr_legal; 1038 #endif 1039 #if defined(INET6) 1040 int local_scope, site_scope, ipv6_addr_legal; 1041 #endif 1042 struct sctp_vrf *vrf; 1043 1044 actual = 0; 1045 if (limit <= 0) 1046 return (actual); 1047 1048 if (stcb) { 1049 /* Turn on all the appropriate scope */ 1050 loopback_scope = stcb->asoc.scope.loopback_scope; 1051 #if defined(INET) 1052 ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; 1053 ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; 1054 #endif 1055 #if defined(INET6) 1056 local_scope = stcb->asoc.scope.local_scope; 1057 site_scope = stcb->asoc.scope.site_scope; 1058 ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; 1059 #endif 1060 } else { 1061 /* Use generic values for endpoints. */ 1062 loopback_scope = 1; 1063 #if defined(INET) 1064 ipv4_local_scope = 1; 1065 #endif 1066 #if defined(INET6) 1067 local_scope = 1; 1068 site_scope = 1; 1069 #endif 1070 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1071 #if defined(INET6) 1072 ipv6_addr_legal = 1; 1073 #endif 1074 #if defined(INET) 1075 if (SCTP_IPV6_V6ONLY(inp)) { 1076 ipv4_addr_legal = 0; 1077 } else { 1078 ipv4_addr_legal = 1; 1079 } 1080 #endif 1081 } else { 1082 #if defined(INET6) 1083 ipv6_addr_legal = 0; 1084 #endif 1085 #if defined(INET) 1086 ipv4_addr_legal = 1; 1087 #endif 1088 } 1089 } 1090 vrf = sctp_find_vrf(vrf_id); 1091 if (vrf == NULL) { 1092 return (0); 1093 } 1094 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1095 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 1096 if ((loopback_scope == 0) && 1097 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { 1098 /* Skip loopback if loopback_scope not set */ 1099 continue; 1100 } 1101 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 1102 if (stcb) { 1103 /* 1104 * For the BOUND-ALL case, the list 1105 * associated with a TCB is Always 1106 * considered a reverse list.. i.e. 1107 * it lists addresses that are NOT 1108 * part of the association. If this 1109 * is one of those we must skip it. 1110 */ 1111 if (sctp_is_addr_restricted(stcb, 1112 sctp_ifa)) { 1113 continue; 1114 } 1115 } 1116 switch (sctp_ifa->address.sa.sa_family) { 1117 #ifdef INET 1118 case AF_INET: 1119 if (ipv4_addr_legal) { 1120 struct sockaddr_in *sin; 1121 1122 sin = &sctp_ifa->address.sin; 1123 if (sin->sin_addr.s_addr == 0) { 1124 /* 1125 * we skip 1126 * unspecifed 1127 * addresses 1128 */ 1129 continue; 1130 } 1131 if (prison_check_ip4(inp->ip_inp.inp.inp_cred, 1132 &sin->sin_addr) != 0) { 1133 continue; 1134 } 1135 if ((ipv4_local_scope == 0) && 1136 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 1137 continue; 1138 } 1139 #ifdef INET6 1140 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 1141 if (actual + sizeof(struct sockaddr_in6) > limit) { 1142 return (actual); 1143 } 1144 in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas); 1145 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1146 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6)); 1147 actual += sizeof(struct sockaddr_in6); 1148 } else { 1149 #endif 1150 if (actual + sizeof(struct sockaddr_in) > limit) { 1151 return (actual); 1152 } 1153 memcpy(sas, sin, sizeof(struct sockaddr_in)); 1154 ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 1155 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in)); 1156 actual += sizeof(struct sockaddr_in); 1157 #ifdef INET6 1158 } 1159 #endif 1160 } else { 1161 continue; 1162 } 1163 break; 1164 #endif 1165 #ifdef INET6 1166 case AF_INET6: 1167 if (ipv6_addr_legal) { 1168 struct sockaddr_in6 *sin6; 1169 1170 sin6 = &sctp_ifa->address.sin6; 1171 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1172 /* 1173 * we skip 1174 * unspecifed 1175 * addresses 1176 */ 1177 continue; 1178 } 1179 if (prison_check_ip6(inp->ip_inp.inp.inp_cred, 1180 &sin6->sin6_addr) != 0) { 1181 continue; 1182 } 1183 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 1184 if (local_scope == 0) 1185 continue; 1186 if (sin6->sin6_scope_id == 0) { 1187 if (sa6_recoverscope(sin6) != 0) 1188 /* 1189 * 1190 * bad 1191 * link 1192 * 1193 * local 1194 * 1195 * address 1196 */ 1197 continue; 1198 } 1199 } 1200 if ((site_scope == 0) && 1201 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 1202 continue; 1203 } 1204 if (actual + sizeof(struct sockaddr_in6) > limit) { 1205 return (actual); 1206 } 1207 memcpy(sas, sin6, sizeof(struct sockaddr_in6)); 1208 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1209 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6)); 1210 actual += sizeof(struct sockaddr_in6); 1211 } else { 1212 continue; 1213 } 1214 break; 1215 #endif 1216 default: 1217 /* TSNH */ 1218 break; 1219 } 1220 } 1221 } 1222 } else { 1223 struct sctp_laddr *laddr; 1224 size_t sa_len; 1225 1226 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1227 if (stcb) { 1228 if (sctp_is_addr_restricted(stcb, laddr->ifa)) { 1229 continue; 1230 } 1231 } 1232 sa_len = laddr->ifa->address.sa.sa_len; 1233 if (actual + sa_len > limit) { 1234 return (actual); 1235 } 1236 if (sctp_fill_user_address(sas, &laddr->ifa->address.sa)) 1237 continue; 1238 switch (laddr->ifa->address.sa.sa_family) { 1239 #ifdef INET 1240 case AF_INET: 1241 ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 1242 break; 1243 #endif 1244 #ifdef INET6 1245 case AF_INET6: 1246 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1247 break; 1248 #endif 1249 default: 1250 /* TSNH */ 1251 break; 1252 } 1253 sas = (struct sockaddr_storage *)((caddr_t)sas + sa_len); 1254 actual += sa_len; 1255 } 1256 } 1257 return (actual); 1258 } 1259 1260 static size_t 1261 sctp_fill_up_addresses(struct sctp_inpcb *inp, 1262 struct sctp_tcb *stcb, 1263 size_t limit, 1264 struct sockaddr_storage *sas) 1265 { 1266 size_t size = 0; 1267 1268 SCTP_IPI_ADDR_RLOCK(); 1269 /* fill up addresses for the endpoint's default vrf */ 1270 size = sctp_fill_up_addresses_vrf(inp, stcb, limit, sas, 1271 inp->def_vrf_id); 1272 SCTP_IPI_ADDR_RUNLOCK(); 1273 return (size); 1274 } 1275 1276 /* 1277 * NOTE: assumes addr lock is held 1278 */ 1279 static int 1280 sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id) 1281 { 1282 int cnt = 0; 1283 struct sctp_vrf *vrf = NULL; 1284 1285 /* 1286 * In both sub-set bound an bound_all cases we return the MAXIMUM 1287 * number of addresses that you COULD get. In reality the sub-set 1288 * bound may have an exclusion list for a given TCB OR in the 1289 * bound-all case a TCB may NOT include the loopback or other 1290 * addresses as well. 1291 */ 1292 vrf = sctp_find_vrf(vrf_id); 1293 if (vrf == NULL) { 1294 return (0); 1295 } 1296 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1297 struct sctp_ifn *sctp_ifn; 1298 struct sctp_ifa *sctp_ifa; 1299 1300 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 1301 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 1302 /* Count them if they are the right type */ 1303 switch (sctp_ifa->address.sa.sa_family) { 1304 #ifdef INET 1305 case AF_INET: 1306 #ifdef INET6 1307 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 1308 cnt += sizeof(struct sockaddr_in6); 1309 else 1310 cnt += sizeof(struct sockaddr_in); 1311 #else 1312 cnt += sizeof(struct sockaddr_in); 1313 #endif 1314 break; 1315 #endif 1316 #ifdef INET6 1317 case AF_INET6: 1318 cnt += sizeof(struct sockaddr_in6); 1319 break; 1320 #endif 1321 default: 1322 break; 1323 } 1324 } 1325 } 1326 } else { 1327 struct sctp_laddr *laddr; 1328 1329 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1330 switch (laddr->ifa->address.sa.sa_family) { 1331 #ifdef INET 1332 case AF_INET: 1333 #ifdef INET6 1334 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 1335 cnt += sizeof(struct sockaddr_in6); 1336 else 1337 cnt += sizeof(struct sockaddr_in); 1338 #else 1339 cnt += sizeof(struct sockaddr_in); 1340 #endif 1341 break; 1342 #endif 1343 #ifdef INET6 1344 case AF_INET6: 1345 cnt += sizeof(struct sockaddr_in6); 1346 break; 1347 #endif 1348 default: 1349 break; 1350 } 1351 } 1352 } 1353 return (cnt); 1354 } 1355 1356 static int 1357 sctp_count_max_addresses(struct sctp_inpcb *inp) 1358 { 1359 int cnt = 0; 1360 1361 SCTP_IPI_ADDR_RLOCK(); 1362 /* count addresses for the endpoint's default VRF */ 1363 cnt = sctp_count_max_addresses_vrf(inp, inp->def_vrf_id); 1364 SCTP_IPI_ADDR_RUNLOCK(); 1365 return (cnt); 1366 } 1367 1368 static int 1369 sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval, 1370 size_t optsize, void *p, int delay) 1371 { 1372 int error; 1373 int creat_lock_on = 0; 1374 struct sctp_tcb *stcb = NULL; 1375 struct sockaddr *sa; 1376 unsigned int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr; 1377 uint32_t vrf_id; 1378 sctp_assoc_t *a_id; 1379 1380 SCTPDBG(SCTP_DEBUG_PCB1, "Connectx called\n"); 1381 1382 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 1383 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 1384 /* We are already connected AND the TCP model */ 1385 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 1386 return (EADDRINUSE); 1387 } 1388 1389 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 1390 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 1391 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1392 return (EINVAL); 1393 } 1394 1395 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 1396 SCTP_INP_RLOCK(inp); 1397 stcb = LIST_FIRST(&inp->sctp_asoc_list); 1398 SCTP_INP_RUNLOCK(inp); 1399 } 1400 if (stcb) { 1401 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 1402 return (EALREADY); 1403 } 1404 SCTP_INP_INCR_REF(inp); 1405 SCTP_ASOC_CREATE_LOCK(inp); 1406 creat_lock_on = 1; 1407 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 1408 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 1409 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 1410 error = EFAULT; 1411 goto out_now; 1412 } 1413 totaddrp = (unsigned int *)optval; 1414 totaddr = *totaddrp; 1415 sa = (struct sockaddr *)(totaddrp + 1); 1416 error = sctp_connectx_helper_find(inp, sa, totaddr, &num_v4, &num_v6, (unsigned int)(optsize - sizeof(int))); 1417 if (error != 0) { 1418 /* Already have or am bring up an association */ 1419 SCTP_ASOC_CREATE_UNLOCK(inp); 1420 creat_lock_on = 0; 1421 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1422 goto out_now; 1423 } 1424 #ifdef INET6 1425 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 1426 (num_v6 > 0)) { 1427 error = EINVAL; 1428 goto out_now; 1429 } 1430 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 1431 (num_v4 > 0)) { 1432 if (SCTP_IPV6_V6ONLY(inp)) { 1433 /* 1434 * if IPV6_V6ONLY flag, ignore connections destined 1435 * to a v4 addr or v4-mapped addr 1436 */ 1437 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1438 error = EINVAL; 1439 goto out_now; 1440 } 1441 } 1442 #endif /* INET6 */ 1443 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 1444 SCTP_PCB_FLAGS_UNBOUND) { 1445 /* Bind a ephemeral port */ 1446 error = sctp_inpcb_bind(so, NULL, NULL, p); 1447 if (error) { 1448 goto out_now; 1449 } 1450 } 1451 1452 /* FIX ME: do we want to pass in a vrf on the connect call? */ 1453 vrf_id = inp->def_vrf_id; 1454 1455 1456 /* We are GOOD to go */ 1457 stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id, 1458 inp->sctp_ep.pre_open_stream_count, 1459 inp->sctp_ep.port, 1460 (struct thread *)p, 1461 SCTP_INITIALIZE_AUTH_PARAMS); 1462 if (stcb == NULL) { 1463 /* Gak! no memory */ 1464 goto out_now; 1465 } 1466 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 1467 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 1468 /* Set the connected flag so we can queue data */ 1469 soisconnecting(so); 1470 } 1471 SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT); 1472 /* move to second address */ 1473 switch (sa->sa_family) { 1474 #ifdef INET 1475 case AF_INET: 1476 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in)); 1477 break; 1478 #endif 1479 #ifdef INET6 1480 case AF_INET6: 1481 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6)); 1482 break; 1483 #endif 1484 default: 1485 break; 1486 } 1487 1488 error = 0; 1489 sctp_connectx_helper_add(stcb, sa, (totaddr - 1), &error); 1490 /* Fill in the return id */ 1491 if (error) { 1492 goto out_now; 1493 } 1494 a_id = (sctp_assoc_t *)optval; 1495 *a_id = sctp_get_associd(stcb); 1496 1497 if (delay) { 1498 /* doing delayed connection */ 1499 stcb->asoc.delayed_connection = 1; 1500 sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination); 1501 } else { 1502 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 1503 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 1504 } 1505 SCTP_TCB_UNLOCK(stcb); 1506 out_now: 1507 if (creat_lock_on) { 1508 SCTP_ASOC_CREATE_UNLOCK(inp); 1509 } 1510 SCTP_INP_DECR_REF(inp); 1511 return (error); 1512 } 1513 1514 #define SCTP_FIND_STCB(inp, stcb, assoc_id) { \ 1515 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||\ 1516 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { \ 1517 SCTP_INP_RLOCK(inp); \ 1518 stcb = LIST_FIRST(&inp->sctp_asoc_list); \ 1519 if (stcb) { \ 1520 SCTP_TCB_LOCK(stcb); \ 1521 } \ 1522 SCTP_INP_RUNLOCK(inp); \ 1523 } else if (assoc_id > SCTP_ALL_ASSOC) { \ 1524 stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \ 1525 if (stcb == NULL) { \ 1526 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \ 1527 error = ENOENT; \ 1528 break; \ 1529 } \ 1530 } else { \ 1531 stcb = NULL; \ 1532 } \ 1533 } 1534 1535 1536 #define SCTP_CHECK_AND_CAST(destp, srcp, type, size) {\ 1537 if (size < sizeof(type)) { \ 1538 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); \ 1539 error = EINVAL; \ 1540 break; \ 1541 } else { \ 1542 destp = (type *)srcp; \ 1543 } \ 1544 } 1545 1546 static int 1547 sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, 1548 void *p) 1549 { 1550 struct sctp_inpcb *inp = NULL; 1551 int error, val = 0; 1552 struct sctp_tcb *stcb = NULL; 1553 1554 if (optval == NULL) { 1555 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1556 return (EINVAL); 1557 } 1558 1559 inp = (struct sctp_inpcb *)so->so_pcb; 1560 if (inp == NULL) { 1561 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1562 return EINVAL; 1563 } 1564 error = 0; 1565 1566 switch (optname) { 1567 case SCTP_NODELAY: 1568 case SCTP_AUTOCLOSE: 1569 case SCTP_EXPLICIT_EOR: 1570 case SCTP_AUTO_ASCONF: 1571 case SCTP_DISABLE_FRAGMENTS: 1572 case SCTP_I_WANT_MAPPED_V4_ADDR: 1573 case SCTP_USE_EXT_RCVINFO: 1574 SCTP_INP_RLOCK(inp); 1575 switch (optname) { 1576 case SCTP_DISABLE_FRAGMENTS: 1577 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT); 1578 break; 1579 case SCTP_I_WANT_MAPPED_V4_ADDR: 1580 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4); 1581 break; 1582 case SCTP_AUTO_ASCONF: 1583 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1584 /* only valid for bound all sockets */ 1585 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 1586 } else { 1587 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1588 error = EINVAL; 1589 goto flags_out; 1590 } 1591 break; 1592 case SCTP_EXPLICIT_EOR: 1593 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); 1594 break; 1595 case SCTP_NODELAY: 1596 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY); 1597 break; 1598 case SCTP_USE_EXT_RCVINFO: 1599 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO); 1600 break; 1601 case SCTP_AUTOCLOSE: 1602 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) 1603 val = sctp_ticks_to_secs(inp->sctp_ep.auto_close_time); 1604 else 1605 val = 0; 1606 break; 1607 1608 default: 1609 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 1610 error = ENOPROTOOPT; 1611 } /* end switch (sopt->sopt_name) */ 1612 if (*optsize < sizeof(val)) { 1613 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1614 error = EINVAL; 1615 } 1616 flags_out: 1617 SCTP_INP_RUNLOCK(inp); 1618 if (error == 0) { 1619 /* return the option value */ 1620 *(int *)optval = val; 1621 *optsize = sizeof(val); 1622 } 1623 break; 1624 case SCTP_GET_PACKET_LOG: 1625 { 1626 #ifdef SCTP_PACKET_LOGGING 1627 uint8_t *target; 1628 int ret; 1629 1630 SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize); 1631 ret = sctp_copy_out_packet_log(target, (int)*optsize); 1632 *optsize = ret; 1633 #else 1634 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 1635 error = EOPNOTSUPP; 1636 #endif 1637 break; 1638 } 1639 case SCTP_REUSE_PORT: 1640 { 1641 uint32_t *value; 1642 1643 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 1644 /* Can't do this for a 1-m socket */ 1645 error = EINVAL; 1646 break; 1647 } 1648 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1649 *value = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 1650 *optsize = sizeof(uint32_t); 1651 break; 1652 } 1653 case SCTP_PARTIAL_DELIVERY_POINT: 1654 { 1655 uint32_t *value; 1656 1657 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1658 *value = inp->partial_delivery_point; 1659 *optsize = sizeof(uint32_t); 1660 break; 1661 } 1662 case SCTP_FRAGMENT_INTERLEAVE: 1663 { 1664 uint32_t *value; 1665 1666 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1667 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) { 1668 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) { 1669 *value = SCTP_FRAG_LEVEL_2; 1670 } else { 1671 *value = SCTP_FRAG_LEVEL_1; 1672 } 1673 } else { 1674 *value = SCTP_FRAG_LEVEL_0; 1675 } 1676 *optsize = sizeof(uint32_t); 1677 break; 1678 } 1679 case SCTP_INTERLEAVING_SUPPORTED: 1680 { 1681 struct sctp_assoc_value *av; 1682 1683 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1684 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1685 1686 if (stcb) { 1687 av->assoc_value = stcb->asoc.idata_supported; 1688 SCTP_TCB_UNLOCK(stcb); 1689 } else { 1690 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1691 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 1692 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 1693 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 1694 SCTP_INP_RLOCK(inp); 1695 if (inp->idata_supported) { 1696 av->assoc_value = 1; 1697 } else { 1698 av->assoc_value = 0; 1699 } 1700 SCTP_INP_RUNLOCK(inp); 1701 } else { 1702 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1703 error = EINVAL; 1704 } 1705 } 1706 if (error == 0) { 1707 *optsize = sizeof(struct sctp_assoc_value); 1708 } 1709 break; 1710 } 1711 case SCTP_CMT_ON_OFF: 1712 { 1713 struct sctp_assoc_value *av; 1714 1715 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1716 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1717 if (stcb) { 1718 av->assoc_value = stcb->asoc.sctp_cmt_on_off; 1719 SCTP_TCB_UNLOCK(stcb); 1720 } else { 1721 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1722 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 1723 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 1724 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 1725 SCTP_INP_RLOCK(inp); 1726 av->assoc_value = inp->sctp_cmt_on_off; 1727 SCTP_INP_RUNLOCK(inp); 1728 } else { 1729 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1730 error = EINVAL; 1731 } 1732 } 1733 if (error == 0) { 1734 *optsize = sizeof(struct sctp_assoc_value); 1735 } 1736 break; 1737 } 1738 case SCTP_PLUGGABLE_CC: 1739 { 1740 struct sctp_assoc_value *av; 1741 1742 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1743 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1744 if (stcb) { 1745 av->assoc_value = stcb->asoc.congestion_control_module; 1746 SCTP_TCB_UNLOCK(stcb); 1747 } else { 1748 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1749 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 1750 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 1751 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 1752 SCTP_INP_RLOCK(inp); 1753 av->assoc_value = inp->sctp_ep.sctp_default_cc_module; 1754 SCTP_INP_RUNLOCK(inp); 1755 } else { 1756 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1757 error = EINVAL; 1758 } 1759 } 1760 if (error == 0) { 1761 *optsize = sizeof(struct sctp_assoc_value); 1762 } 1763 break; 1764 } 1765 case SCTP_CC_OPTION: 1766 { 1767 struct sctp_cc_option *cc_opt; 1768 1769 SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, *optsize); 1770 SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id); 1771 if (stcb == NULL) { 1772 error = EINVAL; 1773 } else { 1774 if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) { 1775 error = ENOTSUP; 1776 } else { 1777 error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option) (stcb, 0, cc_opt); 1778 *optsize = sizeof(struct sctp_cc_option); 1779 } 1780 SCTP_TCB_UNLOCK(stcb); 1781 } 1782 break; 1783 } 1784 case SCTP_PLUGGABLE_SS: 1785 { 1786 struct sctp_assoc_value *av; 1787 1788 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1789 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1790 if (stcb) { 1791 av->assoc_value = stcb->asoc.stream_scheduling_module; 1792 SCTP_TCB_UNLOCK(stcb); 1793 } else { 1794 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1795 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 1796 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 1797 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 1798 SCTP_INP_RLOCK(inp); 1799 av->assoc_value = inp->sctp_ep.sctp_default_ss_module; 1800 SCTP_INP_RUNLOCK(inp); 1801 } else { 1802 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1803 error = EINVAL; 1804 } 1805 } 1806 if (error == 0) { 1807 *optsize = sizeof(struct sctp_assoc_value); 1808 } 1809 break; 1810 } 1811 case SCTP_SS_VALUE: 1812 { 1813 struct sctp_stream_value *av; 1814 1815 SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize); 1816 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1817 if (stcb) { 1818 if ((av->stream_id >= stcb->asoc.streamoutcnt) || 1819 (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], 1820 &av->stream_value) < 0)) { 1821 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1822 error = EINVAL; 1823 } else { 1824 *optsize = sizeof(struct sctp_stream_value); 1825 } 1826 SCTP_TCB_UNLOCK(stcb); 1827 } else { 1828 /* 1829 * Can't get stream value without 1830 * association 1831 */ 1832 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1833 error = EINVAL; 1834 } 1835 break; 1836 } 1837 case SCTP_GET_ADDR_LEN: 1838 { 1839 struct sctp_assoc_value *av; 1840 1841 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1842 error = EINVAL; 1843 #ifdef INET 1844 if (av->assoc_value == AF_INET) { 1845 av->assoc_value = sizeof(struct sockaddr_in); 1846 error = 0; 1847 } 1848 #endif 1849 #ifdef INET6 1850 if (av->assoc_value == AF_INET6) { 1851 av->assoc_value = sizeof(struct sockaddr_in6); 1852 error = 0; 1853 } 1854 #endif 1855 if (error) { 1856 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1857 } else { 1858 *optsize = sizeof(struct sctp_assoc_value); 1859 } 1860 break; 1861 } 1862 case SCTP_GET_ASSOC_NUMBER: 1863 { 1864 uint32_t *value, cnt; 1865 1866 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1867 SCTP_INP_RLOCK(inp); 1868 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1869 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 1870 /* Can't do this for a 1-1 socket */ 1871 error = EINVAL; 1872 SCTP_INP_RUNLOCK(inp); 1873 break; 1874 } 1875 cnt = 0; 1876 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 1877 cnt++; 1878 } 1879 SCTP_INP_RUNLOCK(inp); 1880 *value = cnt; 1881 *optsize = sizeof(uint32_t); 1882 break; 1883 } 1884 case SCTP_GET_ASSOC_ID_LIST: 1885 { 1886 struct sctp_assoc_ids *ids; 1887 uint32_t at; 1888 size_t limit; 1889 1890 SCTP_CHECK_AND_CAST(ids, optval, struct sctp_assoc_ids, *optsize); 1891 SCTP_INP_RLOCK(inp); 1892 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1893 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 1894 /* Can't do this for a 1-1 socket */ 1895 error = EINVAL; 1896 SCTP_INP_RUNLOCK(inp); 1897 break; 1898 } 1899 at = 0; 1900 limit = (*optsize - sizeof(uint32_t)) / sizeof(sctp_assoc_t); 1901 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 1902 if (at < limit) { 1903 ids->gaids_assoc_id[at++] = sctp_get_associd(stcb); 1904 if (at == 0) { 1905 error = EINVAL; 1906 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1907 break; 1908 } 1909 } else { 1910 error = EINVAL; 1911 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1912 break; 1913 } 1914 } 1915 SCTP_INP_RUNLOCK(inp); 1916 if (error == 0) { 1917 ids->gaids_number_of_ids = at; 1918 *optsize = ((at * sizeof(sctp_assoc_t)) + sizeof(uint32_t)); 1919 } 1920 break; 1921 } 1922 case SCTP_CONTEXT: 1923 { 1924 struct sctp_assoc_value *av; 1925 1926 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1927 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1928 1929 if (stcb) { 1930 av->assoc_value = stcb->asoc.context; 1931 SCTP_TCB_UNLOCK(stcb); 1932 } else { 1933 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1934 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 1935 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 1936 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 1937 SCTP_INP_RLOCK(inp); 1938 av->assoc_value = inp->sctp_context; 1939 SCTP_INP_RUNLOCK(inp); 1940 } else { 1941 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1942 error = EINVAL; 1943 } 1944 } 1945 if (error == 0) { 1946 *optsize = sizeof(struct sctp_assoc_value); 1947 } 1948 break; 1949 } 1950 case SCTP_VRF_ID: 1951 { 1952 uint32_t *default_vrfid; 1953 1954 SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, *optsize); 1955 *default_vrfid = inp->def_vrf_id; 1956 *optsize = sizeof(uint32_t); 1957 break; 1958 } 1959 case SCTP_GET_ASOC_VRF: 1960 { 1961 struct sctp_assoc_value *id; 1962 1963 SCTP_CHECK_AND_CAST(id, optval, struct sctp_assoc_value, *optsize); 1964 SCTP_FIND_STCB(inp, stcb, id->assoc_id); 1965 if (stcb == NULL) { 1966 error = EINVAL; 1967 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1968 } else { 1969 id->assoc_value = stcb->asoc.vrf_id; 1970 SCTP_TCB_UNLOCK(stcb); 1971 *optsize = sizeof(struct sctp_assoc_value); 1972 } 1973 break; 1974 } 1975 case SCTP_GET_VRF_IDS: 1976 { 1977 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 1978 error = EOPNOTSUPP; 1979 break; 1980 } 1981 case SCTP_GET_NONCE_VALUES: 1982 { 1983 struct sctp_get_nonce_values *gnv; 1984 1985 SCTP_CHECK_AND_CAST(gnv, optval, struct sctp_get_nonce_values, *optsize); 1986 SCTP_FIND_STCB(inp, stcb, gnv->gn_assoc_id); 1987 1988 if (stcb) { 1989 gnv->gn_peers_tag = stcb->asoc.peer_vtag; 1990 gnv->gn_local_tag = stcb->asoc.my_vtag; 1991 SCTP_TCB_UNLOCK(stcb); 1992 *optsize = sizeof(struct sctp_get_nonce_values); 1993 } else { 1994 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 1995 error = ENOTCONN; 1996 } 1997 break; 1998 } 1999 case SCTP_DELAYED_SACK: 2000 { 2001 struct sctp_sack_info *sack; 2002 2003 SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, *optsize); 2004 SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 2005 if (stcb) { 2006 sack->sack_delay = stcb->asoc.delayed_ack; 2007 sack->sack_freq = stcb->asoc.sack_freq; 2008 SCTP_TCB_UNLOCK(stcb); 2009 } else { 2010 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2011 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2012 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2013 (sack->sack_assoc_id == SCTP_FUTURE_ASSOC))) { 2014 SCTP_INP_RLOCK(inp); 2015 sack->sack_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 2016 sack->sack_freq = inp->sctp_ep.sctp_sack_freq; 2017 SCTP_INP_RUNLOCK(inp); 2018 } else { 2019 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2020 error = EINVAL; 2021 } 2022 } 2023 if (error == 0) { 2024 *optsize = sizeof(struct sctp_sack_info); 2025 } 2026 break; 2027 } 2028 case SCTP_GET_SNDBUF_USE: 2029 { 2030 struct sctp_sockstat *ss; 2031 2032 SCTP_CHECK_AND_CAST(ss, optval, struct sctp_sockstat, *optsize); 2033 SCTP_FIND_STCB(inp, stcb, ss->ss_assoc_id); 2034 2035 if (stcb) { 2036 ss->ss_total_sndbuf = stcb->asoc.total_output_queue_size; 2037 ss->ss_total_recv_buf = (stcb->asoc.size_on_reasm_queue + 2038 stcb->asoc.size_on_all_streams); 2039 SCTP_TCB_UNLOCK(stcb); 2040 *optsize = sizeof(struct sctp_sockstat); 2041 } else { 2042 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 2043 error = ENOTCONN; 2044 } 2045 break; 2046 } 2047 case SCTP_MAX_BURST: 2048 { 2049 struct sctp_assoc_value *av; 2050 2051 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 2052 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 2053 2054 if (stcb) { 2055 av->assoc_value = stcb->asoc.max_burst; 2056 SCTP_TCB_UNLOCK(stcb); 2057 } else { 2058 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2059 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2060 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2061 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 2062 SCTP_INP_RLOCK(inp); 2063 av->assoc_value = inp->sctp_ep.max_burst; 2064 SCTP_INP_RUNLOCK(inp); 2065 } else { 2066 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2067 error = EINVAL; 2068 } 2069 } 2070 if (error == 0) { 2071 *optsize = sizeof(struct sctp_assoc_value); 2072 } 2073 break; 2074 } 2075 case SCTP_MAXSEG: 2076 { 2077 struct sctp_assoc_value *av; 2078 int ovh; 2079 2080 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 2081 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 2082 2083 if (stcb) { 2084 av->assoc_value = sctp_get_frag_point(stcb, &stcb->asoc); 2085 SCTP_TCB_UNLOCK(stcb); 2086 } else { 2087 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2088 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2089 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2090 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 2091 SCTP_INP_RLOCK(inp); 2092 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 2093 ovh = SCTP_MED_OVERHEAD; 2094 } else { 2095 ovh = SCTP_MED_V4_OVERHEAD; 2096 } 2097 if (inp->sctp_frag_point >= SCTP_DEFAULT_MAXSEGMENT) 2098 av->assoc_value = 0; 2099 else 2100 av->assoc_value = inp->sctp_frag_point - ovh; 2101 SCTP_INP_RUNLOCK(inp); 2102 } else { 2103 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2104 error = EINVAL; 2105 } 2106 } 2107 if (error == 0) { 2108 *optsize = sizeof(struct sctp_assoc_value); 2109 } 2110 break; 2111 } 2112 case SCTP_GET_STAT_LOG: 2113 error = sctp_fill_stat_log(optval, optsize); 2114 break; 2115 case SCTP_EVENTS: 2116 { 2117 struct sctp_event_subscribe *events; 2118 2119 SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, *optsize); 2120 memset(events, 0, sizeof(struct sctp_event_subscribe)); 2121 SCTP_INP_RLOCK(inp); 2122 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT)) 2123 events->sctp_data_io_event = 1; 2124 2125 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT)) 2126 events->sctp_association_event = 1; 2127 2128 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT)) 2129 events->sctp_address_event = 1; 2130 2131 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) 2132 events->sctp_send_failure_event = 1; 2133 2134 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR)) 2135 events->sctp_peer_error_event = 1; 2136 2137 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) 2138 events->sctp_shutdown_event = 1; 2139 2140 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT)) 2141 events->sctp_partial_delivery_event = 1; 2142 2143 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) 2144 events->sctp_adaptation_layer_event = 1; 2145 2146 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT)) 2147 events->sctp_authentication_event = 1; 2148 2149 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT)) 2150 events->sctp_sender_dry_event = 1; 2151 2152 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT)) 2153 events->sctp_stream_reset_event = 1; 2154 SCTP_INP_RUNLOCK(inp); 2155 *optsize = sizeof(struct sctp_event_subscribe); 2156 break; 2157 } 2158 case SCTP_ADAPTATION_LAYER: 2159 { 2160 uint32_t *value; 2161 2162 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 2163 2164 SCTP_INP_RLOCK(inp); 2165 *value = inp->sctp_ep.adaptation_layer_indicator; 2166 SCTP_INP_RUNLOCK(inp); 2167 *optsize = sizeof(uint32_t); 2168 break; 2169 } 2170 case SCTP_SET_INITIAL_DBG_SEQ: 2171 { 2172 uint32_t *value; 2173 2174 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 2175 SCTP_INP_RLOCK(inp); 2176 *value = inp->sctp_ep.initial_sequence_debug; 2177 SCTP_INP_RUNLOCK(inp); 2178 *optsize = sizeof(uint32_t); 2179 break; 2180 } 2181 case SCTP_GET_LOCAL_ADDR_SIZE: 2182 { 2183 uint32_t *value; 2184 2185 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 2186 SCTP_INP_RLOCK(inp); 2187 *value = sctp_count_max_addresses(inp); 2188 SCTP_INP_RUNLOCK(inp); 2189 *optsize = sizeof(uint32_t); 2190 break; 2191 } 2192 case SCTP_GET_REMOTE_ADDR_SIZE: 2193 { 2194 uint32_t *value; 2195 size_t size; 2196 struct sctp_nets *net; 2197 2198 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 2199 /* FIXME MT: change to sctp_assoc_value? */ 2200 SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t)*value); 2201 2202 if (stcb) { 2203 size = 0; 2204 /* Count the sizes */ 2205 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2206 switch (net->ro._l_addr.sa.sa_family) { 2207 #ifdef INET 2208 case AF_INET: 2209 #ifdef INET6 2210 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 2211 size += sizeof(struct sockaddr_in6); 2212 } else { 2213 size += sizeof(struct sockaddr_in); 2214 } 2215 #else 2216 size += sizeof(struct sockaddr_in); 2217 #endif 2218 break; 2219 #endif 2220 #ifdef INET6 2221 case AF_INET6: 2222 size += sizeof(struct sockaddr_in6); 2223 break; 2224 #endif 2225 default: 2226 break; 2227 } 2228 } 2229 SCTP_TCB_UNLOCK(stcb); 2230 *value = (uint32_t)size; 2231 *optsize = sizeof(uint32_t); 2232 } else { 2233 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 2234 error = ENOTCONN; 2235 } 2236 break; 2237 } 2238 case SCTP_GET_PEER_ADDRESSES: 2239 /* 2240 * Get the address information, an array is passed in to 2241 * fill up we pack it. 2242 */ 2243 { 2244 size_t cpsz, left; 2245 struct sockaddr_storage *sas; 2246 struct sctp_nets *net; 2247 struct sctp_getaddresses *saddr; 2248 2249 SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 2250 SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 2251 2252 if (stcb) { 2253 left = (*optsize) - sizeof(sctp_assoc_t); 2254 *optsize = sizeof(sctp_assoc_t); 2255 sas = (struct sockaddr_storage *)&saddr->addr[0]; 2256 2257 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2258 switch (net->ro._l_addr.sa.sa_family) { 2259 #ifdef INET 2260 case AF_INET: 2261 #ifdef INET6 2262 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 2263 cpsz = sizeof(struct sockaddr_in6); 2264 } else { 2265 cpsz = sizeof(struct sockaddr_in); 2266 } 2267 #else 2268 cpsz = sizeof(struct sockaddr_in); 2269 #endif 2270 break; 2271 #endif 2272 #ifdef INET6 2273 case AF_INET6: 2274 cpsz = sizeof(struct sockaddr_in6); 2275 break; 2276 #endif 2277 default: 2278 cpsz = 0; 2279 break; 2280 } 2281 if (cpsz == 0) { 2282 break; 2283 } 2284 if (left < cpsz) { 2285 /* not enough room. */ 2286 break; 2287 } 2288 #if defined(INET) && defined(INET6) 2289 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) && 2290 (net->ro._l_addr.sa.sa_family == AF_INET)) { 2291 /* Must map the address */ 2292 in6_sin_2_v4mapsin6(&net->ro._l_addr.sin, 2293 (struct sockaddr_in6 *)sas); 2294 } else { 2295 memcpy(sas, &net->ro._l_addr, cpsz); 2296 } 2297 #else 2298 memcpy(sas, &net->ro._l_addr, cpsz); 2299 #endif 2300 ((struct sockaddr_in *)sas)->sin_port = stcb->rport; 2301 2302 sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz); 2303 left -= cpsz; 2304 *optsize += cpsz; 2305 } 2306 SCTP_TCB_UNLOCK(stcb); 2307 } else { 2308 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 2309 error = ENOENT; 2310 } 2311 break; 2312 } 2313 case SCTP_GET_LOCAL_ADDRESSES: 2314 { 2315 size_t limit, actual; 2316 struct sockaddr_storage *sas; 2317 struct sctp_getaddresses *saddr; 2318 2319 SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 2320 SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 2321 2322 sas = (struct sockaddr_storage *)&saddr->addr[0]; 2323 limit = *optsize - sizeof(sctp_assoc_t); 2324 actual = sctp_fill_up_addresses(inp, stcb, limit, sas); 2325 if (stcb) { 2326 SCTP_TCB_UNLOCK(stcb); 2327 } 2328 *optsize = sizeof(sctp_assoc_t) + actual; 2329 break; 2330 } 2331 case SCTP_PEER_ADDR_PARAMS: 2332 { 2333 struct sctp_paddrparams *paddrp; 2334 struct sctp_nets *net; 2335 struct sockaddr *addr; 2336 #if defined(INET) && defined(INET6) 2337 struct sockaddr_in sin_store; 2338 #endif 2339 2340 SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize); 2341 SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 2342 2343 #if defined(INET) && defined(INET6) 2344 if (paddrp->spp_address.ss_family == AF_INET6) { 2345 struct sockaddr_in6 *sin6; 2346 2347 sin6 = (struct sockaddr_in6 *)&paddrp->spp_address; 2348 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 2349 in6_sin6_2_sin(&sin_store, sin6); 2350 addr = (struct sockaddr *)&sin_store; 2351 } else { 2352 addr = (struct sockaddr *)&paddrp->spp_address; 2353 } 2354 } else { 2355 addr = (struct sockaddr *)&paddrp->spp_address; 2356 } 2357 #else 2358 addr = (struct sockaddr *)&paddrp->spp_address; 2359 #endif 2360 if (stcb != NULL) { 2361 net = sctp_findnet(stcb, addr); 2362 } else { 2363 /* 2364 * We increment here since 2365 * sctp_findassociation_ep_addr() wil do a 2366 * decrement if it finds the stcb as long as 2367 * the locked tcb (last argument) is NOT a 2368 * TCB.. aka NULL. 2369 */ 2370 net = NULL; 2371 SCTP_INP_INCR_REF(inp); 2372 stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL); 2373 if (stcb == NULL) { 2374 SCTP_INP_DECR_REF(inp); 2375 } 2376 } 2377 if ((stcb != NULL) && (net == NULL)) { 2378 #ifdef INET 2379 if (addr->sa_family == AF_INET) { 2380 struct sockaddr_in *sin; 2381 2382 sin = (struct sockaddr_in *)addr; 2383 if (sin->sin_addr.s_addr != INADDR_ANY) { 2384 error = EINVAL; 2385 SCTP_TCB_UNLOCK(stcb); 2386 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2387 break; 2388 } 2389 } else 2390 #endif 2391 #ifdef INET6 2392 if (addr->sa_family == AF_INET6) { 2393 struct sockaddr_in6 *sin6; 2394 2395 sin6 = (struct sockaddr_in6 *)addr; 2396 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 2397 error = EINVAL; 2398 SCTP_TCB_UNLOCK(stcb); 2399 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2400 break; 2401 } 2402 } else 2403 #endif 2404 { 2405 error = EAFNOSUPPORT; 2406 SCTP_TCB_UNLOCK(stcb); 2407 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2408 break; 2409 } 2410 } 2411 2412 if (stcb != NULL) { 2413 /* Applies to the specific association */ 2414 paddrp->spp_flags = 0; 2415 if (net != NULL) { 2416 paddrp->spp_hbinterval = net->heart_beat_delay; 2417 paddrp->spp_pathmaxrxt = net->failure_threshold; 2418 paddrp->spp_pathmtu = net->mtu; 2419 switch (net->ro._l_addr.sa.sa_family) { 2420 #ifdef INET 2421 case AF_INET: 2422 paddrp->spp_pathmtu -= SCTP_MIN_V4_OVERHEAD; 2423 break; 2424 #endif 2425 #ifdef INET6 2426 case AF_INET6: 2427 paddrp->spp_pathmtu -= SCTP_MIN_OVERHEAD; 2428 break; 2429 #endif 2430 default: 2431 break; 2432 } 2433 /* get flags for HB */ 2434 if (net->dest_state & SCTP_ADDR_NOHB) { 2435 paddrp->spp_flags |= SPP_HB_DISABLE; 2436 } else { 2437 paddrp->spp_flags |= SPP_HB_ENABLE; 2438 } 2439 /* get flags for PMTU */ 2440 if (net->dest_state & SCTP_ADDR_NO_PMTUD) { 2441 paddrp->spp_flags |= SPP_PMTUD_DISABLE; 2442 } else { 2443 paddrp->spp_flags |= SPP_PMTUD_ENABLE; 2444 } 2445 if (net->dscp & 0x01) { 2446 paddrp->spp_dscp = net->dscp & 0xfc; 2447 paddrp->spp_flags |= SPP_DSCP; 2448 } 2449 #ifdef INET6 2450 if ((net->ro._l_addr.sa.sa_family == AF_INET6) && 2451 (net->flowlabel & 0x80000000)) { 2452 paddrp->spp_ipv6_flowlabel = net->flowlabel & 0x000fffff; 2453 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2454 } 2455 #endif 2456 } else { 2457 /* 2458 * No destination so return default 2459 * value 2460 */ 2461 paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure; 2462 paddrp->spp_pathmtu = stcb->asoc.default_mtu; 2463 if (stcb->asoc.default_dscp & 0x01) { 2464 paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc; 2465 paddrp->spp_flags |= SPP_DSCP; 2466 } 2467 #ifdef INET6 2468 if (stcb->asoc.default_flowlabel & 0x80000000) { 2469 paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel & 0x000fffff; 2470 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2471 } 2472 #endif 2473 /* default settings should be these */ 2474 if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { 2475 paddrp->spp_flags |= SPP_HB_DISABLE; 2476 } else { 2477 paddrp->spp_flags |= SPP_HB_ENABLE; 2478 } 2479 if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) { 2480 paddrp->spp_flags |= SPP_PMTUD_DISABLE; 2481 } else { 2482 paddrp->spp_flags |= SPP_PMTUD_ENABLE; 2483 } 2484 paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay; 2485 } 2486 paddrp->spp_assoc_id = sctp_get_associd(stcb); 2487 SCTP_TCB_UNLOCK(stcb); 2488 } else { 2489 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2490 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2491 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2492 (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC))) { 2493 /* Use endpoint defaults */ 2494 SCTP_INP_RLOCK(inp); 2495 paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure; 2496 paddrp->spp_hbinterval = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 2497 paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC; 2498 /* get inp's default */ 2499 if (inp->sctp_ep.default_dscp & 0x01) { 2500 paddrp->spp_dscp = inp->sctp_ep.default_dscp & 0xfc; 2501 paddrp->spp_flags |= SPP_DSCP; 2502 } 2503 #ifdef INET6 2504 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 2505 (inp->sctp_ep.default_flowlabel & 0x80000000)) { 2506 paddrp->spp_ipv6_flowlabel = inp->sctp_ep.default_flowlabel & 0x000fffff; 2507 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2508 } 2509 #endif 2510 paddrp->spp_pathmtu = inp->sctp_ep.default_mtu; 2511 2512 if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { 2513 paddrp->spp_flags |= SPP_HB_ENABLE; 2514 } else { 2515 paddrp->spp_flags |= SPP_HB_DISABLE; 2516 } 2517 if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) { 2518 paddrp->spp_flags |= SPP_PMTUD_ENABLE; 2519 } else { 2520 paddrp->spp_flags |= SPP_PMTUD_DISABLE; 2521 } 2522 SCTP_INP_RUNLOCK(inp); 2523 } else { 2524 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2525 error = EINVAL; 2526 } 2527 } 2528 if (error == 0) { 2529 *optsize = sizeof(struct sctp_paddrparams); 2530 } 2531 break; 2532 } 2533 case SCTP_GET_PEER_ADDR_INFO: 2534 { 2535 struct sctp_paddrinfo *paddri; 2536 struct sctp_nets *net; 2537 struct sockaddr *addr; 2538 #if defined(INET) && defined(INET6) 2539 struct sockaddr_in sin_store; 2540 #endif 2541 2542 SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize); 2543 SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id); 2544 2545 #if defined(INET) && defined(INET6) 2546 if (paddri->spinfo_address.ss_family == AF_INET6) { 2547 struct sockaddr_in6 *sin6; 2548 2549 sin6 = (struct sockaddr_in6 *)&paddri->spinfo_address; 2550 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 2551 in6_sin6_2_sin(&sin_store, sin6); 2552 addr = (struct sockaddr *)&sin_store; 2553 } else { 2554 addr = (struct sockaddr *)&paddri->spinfo_address; 2555 } 2556 } else { 2557 addr = (struct sockaddr *)&paddri->spinfo_address; 2558 } 2559 #else 2560 addr = (struct sockaddr *)&paddri->spinfo_address; 2561 #endif 2562 if (stcb != NULL) { 2563 net = sctp_findnet(stcb, addr); 2564 } else { 2565 /* 2566 * We increment here since 2567 * sctp_findassociation_ep_addr() wil do a 2568 * decrement if it finds the stcb as long as 2569 * the locked tcb (last argument) is NOT a 2570 * TCB.. aka NULL. 2571 */ 2572 net = NULL; 2573 SCTP_INP_INCR_REF(inp); 2574 stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL); 2575 if (stcb == NULL) { 2576 SCTP_INP_DECR_REF(inp); 2577 } 2578 } 2579 2580 if ((stcb != NULL) && (net != NULL)) { 2581 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { 2582 /* It's unconfirmed */ 2583 paddri->spinfo_state = SCTP_UNCONFIRMED; 2584 } else if (net->dest_state & SCTP_ADDR_REACHABLE) { 2585 /* It's active */ 2586 paddri->spinfo_state = SCTP_ACTIVE; 2587 } else { 2588 /* It's inactive */ 2589 paddri->spinfo_state = SCTP_INACTIVE; 2590 } 2591 paddri->spinfo_cwnd = net->cwnd; 2592 paddri->spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT; 2593 paddri->spinfo_rto = net->RTO; 2594 paddri->spinfo_assoc_id = sctp_get_associd(stcb); 2595 paddri->spinfo_mtu = net->mtu; 2596 switch (addr->sa_family) { 2597 #if defined(INET) 2598 case AF_INET: 2599 paddri->spinfo_mtu -= SCTP_MIN_V4_OVERHEAD; 2600 break; 2601 #endif 2602 #if defined(INET6) 2603 case AF_INET6: 2604 paddri->spinfo_mtu -= SCTP_MIN_OVERHEAD; 2605 break; 2606 #endif 2607 default: 2608 break; 2609 } 2610 SCTP_TCB_UNLOCK(stcb); 2611 *optsize = sizeof(struct sctp_paddrinfo); 2612 } else { 2613 if (stcb != NULL) { 2614 SCTP_TCB_UNLOCK(stcb); 2615 } 2616 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 2617 error = ENOENT; 2618 } 2619 break; 2620 } 2621 case SCTP_PCB_STATUS: 2622 { 2623 struct sctp_pcbinfo *spcb; 2624 2625 SCTP_CHECK_AND_CAST(spcb, optval, struct sctp_pcbinfo, *optsize); 2626 sctp_fill_pcbinfo(spcb); 2627 *optsize = sizeof(struct sctp_pcbinfo); 2628 break; 2629 } 2630 case SCTP_STATUS: 2631 { 2632 struct sctp_nets *net; 2633 struct sctp_status *sstat; 2634 2635 SCTP_CHECK_AND_CAST(sstat, optval, struct sctp_status, *optsize); 2636 SCTP_FIND_STCB(inp, stcb, sstat->sstat_assoc_id); 2637 2638 if (stcb == NULL) { 2639 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2640 error = EINVAL; 2641 break; 2642 } 2643 sstat->sstat_state = sctp_map_assoc_state(stcb->asoc.state); 2644 sstat->sstat_assoc_id = sctp_get_associd(stcb); 2645 sstat->sstat_rwnd = stcb->asoc.peers_rwnd; 2646 sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt; 2647 /* 2648 * We can't include chunks that have been passed to 2649 * the socket layer. Only things in queue. 2650 */ 2651 sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue + 2652 stcb->asoc.cnt_on_all_streams); 2653 2654 2655 sstat->sstat_instrms = stcb->asoc.streamincnt; 2656 sstat->sstat_outstrms = stcb->asoc.streamoutcnt; 2657 sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc); 2658 net = stcb->asoc.primary_destination; 2659 if (net != NULL) { 2660 memcpy(&sstat->sstat_primary.spinfo_address, 2661 &net->ro._l_addr, 2662 ((struct sockaddr *)(&net->ro._l_addr))->sa_len); 2663 ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport; 2664 /* 2665 * Again the user can get info from 2666 * sctp_constants.h for what the state of 2667 * the network is. 2668 */ 2669 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { 2670 /* It's unconfirmed */ 2671 sstat->sstat_primary.spinfo_state = SCTP_UNCONFIRMED; 2672 } else if (net->dest_state & SCTP_ADDR_REACHABLE) { 2673 /* It's active */ 2674 sstat->sstat_primary.spinfo_state = SCTP_ACTIVE; 2675 } else { 2676 /* It's inactive */ 2677 sstat->sstat_primary.spinfo_state = SCTP_INACTIVE; 2678 } 2679 sstat->sstat_primary.spinfo_cwnd = net->cwnd; 2680 sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT; 2681 sstat->sstat_primary.spinfo_rto = net->RTO; 2682 sstat->sstat_primary.spinfo_mtu = net->mtu; 2683 switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) { 2684 #if defined(INET) 2685 case AF_INET: 2686 sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_V4_OVERHEAD; 2687 break; 2688 #endif 2689 #if defined(INET6) 2690 case AF_INET6: 2691 sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_OVERHEAD; 2692 break; 2693 #endif 2694 default: 2695 break; 2696 } 2697 } else { 2698 memset(&sstat->sstat_primary, 0, sizeof(struct sctp_paddrinfo)); 2699 } 2700 sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb); 2701 SCTP_TCB_UNLOCK(stcb); 2702 *optsize = sizeof(struct sctp_status); 2703 break; 2704 } 2705 case SCTP_RTOINFO: 2706 { 2707 struct sctp_rtoinfo *srto; 2708 2709 SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, *optsize); 2710 SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 2711 2712 if (stcb) { 2713 srto->srto_initial = stcb->asoc.initial_rto; 2714 srto->srto_max = stcb->asoc.maxrto; 2715 srto->srto_min = stcb->asoc.minrto; 2716 SCTP_TCB_UNLOCK(stcb); 2717 } else { 2718 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2719 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2720 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2721 (srto->srto_assoc_id == SCTP_FUTURE_ASSOC))) { 2722 SCTP_INP_RLOCK(inp); 2723 srto->srto_initial = inp->sctp_ep.initial_rto; 2724 srto->srto_max = inp->sctp_ep.sctp_maxrto; 2725 srto->srto_min = inp->sctp_ep.sctp_minrto; 2726 SCTP_INP_RUNLOCK(inp); 2727 } else { 2728 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2729 error = EINVAL; 2730 } 2731 } 2732 if (error == 0) { 2733 *optsize = sizeof(struct sctp_rtoinfo); 2734 } 2735 break; 2736 } 2737 case SCTP_TIMEOUTS: 2738 { 2739 struct sctp_timeouts *stimo; 2740 2741 SCTP_CHECK_AND_CAST(stimo, optval, struct sctp_timeouts, *optsize); 2742 SCTP_FIND_STCB(inp, stcb, stimo->stimo_assoc_id); 2743 2744 if (stcb) { 2745 stimo->stimo_init = stcb->asoc.timoinit; 2746 stimo->stimo_data = stcb->asoc.timodata; 2747 stimo->stimo_sack = stcb->asoc.timosack; 2748 stimo->stimo_shutdown = stcb->asoc.timoshutdown; 2749 stimo->stimo_heartbeat = stcb->asoc.timoheartbeat; 2750 stimo->stimo_cookie = stcb->asoc.timocookie; 2751 stimo->stimo_shutdownack = stcb->asoc.timoshutdownack; 2752 SCTP_TCB_UNLOCK(stcb); 2753 *optsize = sizeof(struct sctp_timeouts); 2754 } else { 2755 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2756 error = EINVAL; 2757 } 2758 break; 2759 } 2760 case SCTP_ASSOCINFO: 2761 { 2762 struct sctp_assocparams *sasoc; 2763 2764 SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, *optsize); 2765 SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 2766 2767 if (stcb) { 2768 sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(stcb->asoc.cookie_life); 2769 sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times; 2770 sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets; 2771 sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd; 2772 sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd; 2773 SCTP_TCB_UNLOCK(stcb); 2774 } else { 2775 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2776 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2777 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2778 (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) { 2779 SCTP_INP_RLOCK(inp); 2780 sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(inp->sctp_ep.def_cookie_life); 2781 sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times; 2782 sasoc->sasoc_number_peer_destinations = 0; 2783 sasoc->sasoc_peer_rwnd = 0; 2784 sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv); 2785 SCTP_INP_RUNLOCK(inp); 2786 } else { 2787 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2788 error = EINVAL; 2789 } 2790 } 2791 if (error == 0) { 2792 *optsize = sizeof(struct sctp_assocparams); 2793 } 2794 break; 2795 } 2796 case SCTP_DEFAULT_SEND_PARAM: 2797 { 2798 struct sctp_sndrcvinfo *s_info; 2799 2800 SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, *optsize); 2801 SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 2802 2803 if (stcb) { 2804 memcpy(s_info, &stcb->asoc.def_send, sizeof(stcb->asoc.def_send)); 2805 SCTP_TCB_UNLOCK(stcb); 2806 } else { 2807 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2808 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2809 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2810 (s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC))) { 2811 SCTP_INP_RLOCK(inp); 2812 memcpy(s_info, &inp->def_send, sizeof(inp->def_send)); 2813 SCTP_INP_RUNLOCK(inp); 2814 } else { 2815 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2816 error = EINVAL; 2817 } 2818 } 2819 if (error == 0) { 2820 *optsize = sizeof(struct sctp_sndrcvinfo); 2821 } 2822 break; 2823 } 2824 case SCTP_INITMSG: 2825 { 2826 struct sctp_initmsg *sinit; 2827 2828 SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, *optsize); 2829 SCTP_INP_RLOCK(inp); 2830 sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count; 2831 sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome; 2832 sinit->sinit_max_attempts = inp->sctp_ep.max_init_times; 2833 sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max; 2834 SCTP_INP_RUNLOCK(inp); 2835 *optsize = sizeof(struct sctp_initmsg); 2836 break; 2837 } 2838 case SCTP_PRIMARY_ADDR: 2839 /* we allow a "get" operation on this */ 2840 { 2841 struct sctp_setprim *ssp; 2842 2843 SCTP_CHECK_AND_CAST(ssp, optval, struct sctp_setprim, *optsize); 2844 SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id); 2845 2846 if (stcb) { 2847 union sctp_sockstore *addr; 2848 2849 addr = &stcb->asoc.primary_destination->ro._l_addr; 2850 switch (addr->sa.sa_family) { 2851 #ifdef INET 2852 case AF_INET: 2853 #ifdef INET6 2854 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 2855 in6_sin_2_v4mapsin6(&addr->sin, 2856 (struct sockaddr_in6 *)&ssp->ssp_addr); 2857 } else { 2858 memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in)); 2859 } 2860 #else 2861 memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in)); 2862 #endif 2863 break; 2864 #endif 2865 #ifdef INET6 2866 case AF_INET6: 2867 memcpy(&ssp->ssp_addr, &addr->sin6, sizeof(struct sockaddr_in6)); 2868 break; 2869 #endif 2870 default: 2871 break; 2872 } 2873 SCTP_TCB_UNLOCK(stcb); 2874 *optsize = sizeof(struct sctp_setprim); 2875 } else { 2876 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2877 error = EINVAL; 2878 } 2879 break; 2880 } 2881 case SCTP_HMAC_IDENT: 2882 { 2883 struct sctp_hmacalgo *shmac; 2884 sctp_hmaclist_t *hmaclist; 2885 uint32_t size; 2886 int i; 2887 2888 SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize); 2889 2890 SCTP_INP_RLOCK(inp); 2891 hmaclist = inp->sctp_ep.local_hmacs; 2892 if (hmaclist == NULL) { 2893 /* no HMACs to return */ 2894 *optsize = sizeof(*shmac); 2895 SCTP_INP_RUNLOCK(inp); 2896 break; 2897 } 2898 /* is there room for all of the hmac ids? */ 2899 size = sizeof(*shmac) + (hmaclist->num_algo * 2900 sizeof(shmac->shmac_idents[0])); 2901 if ((size_t)(*optsize) < size) { 2902 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2903 error = EINVAL; 2904 SCTP_INP_RUNLOCK(inp); 2905 break; 2906 } 2907 /* copy in the list */ 2908 shmac->shmac_number_of_idents = hmaclist->num_algo; 2909 for (i = 0; i < hmaclist->num_algo; i++) { 2910 shmac->shmac_idents[i] = hmaclist->hmac[i]; 2911 } 2912 SCTP_INP_RUNLOCK(inp); 2913 *optsize = size; 2914 break; 2915 } 2916 case SCTP_AUTH_ACTIVE_KEY: 2917 { 2918 struct sctp_authkeyid *scact; 2919 2920 SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, *optsize); 2921 SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 2922 2923 if (stcb) { 2924 /* get the active key on the assoc */ 2925 scact->scact_keynumber = stcb->asoc.authinfo.active_keyid; 2926 SCTP_TCB_UNLOCK(stcb); 2927 } else { 2928 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2929 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2930 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2931 (scact->scact_assoc_id == SCTP_FUTURE_ASSOC))) { 2932 /* get the endpoint active key */ 2933 SCTP_INP_RLOCK(inp); 2934 scact->scact_keynumber = inp->sctp_ep.default_keyid; 2935 SCTP_INP_RUNLOCK(inp); 2936 } else { 2937 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2938 error = EINVAL; 2939 } 2940 } 2941 if (error == 0) { 2942 *optsize = sizeof(struct sctp_authkeyid); 2943 } 2944 break; 2945 } 2946 case SCTP_LOCAL_AUTH_CHUNKS: 2947 { 2948 struct sctp_authchunks *sac; 2949 sctp_auth_chklist_t *chklist = NULL; 2950 size_t size = 0; 2951 2952 SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 2953 SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 2954 2955 if (stcb) { 2956 /* get off the assoc */ 2957 chklist = stcb->asoc.local_auth_chunks; 2958 /* is there enough space? */ 2959 size = sctp_auth_get_chklist_size(chklist); 2960 if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 2961 error = EINVAL; 2962 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2963 } else { 2964 /* copy in the chunks */ 2965 (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 2966 sac->gauth_number_of_chunks = (uint32_t)size; 2967 *optsize = sizeof(struct sctp_authchunks) + size; 2968 } 2969 SCTP_TCB_UNLOCK(stcb); 2970 } else { 2971 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2972 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 2973 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 2974 (sac->gauth_assoc_id == SCTP_FUTURE_ASSOC))) { 2975 /* get off the endpoint */ 2976 SCTP_INP_RLOCK(inp); 2977 chklist = inp->sctp_ep.local_auth_chunks; 2978 /* is there enough space? */ 2979 size = sctp_auth_get_chklist_size(chklist); 2980 if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 2981 error = EINVAL; 2982 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2983 } else { 2984 /* copy in the chunks */ 2985 (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 2986 sac->gauth_number_of_chunks = (uint32_t)size; 2987 *optsize = sizeof(struct sctp_authchunks) + size; 2988 } 2989 SCTP_INP_RUNLOCK(inp); 2990 } else { 2991 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2992 error = EINVAL; 2993 } 2994 } 2995 break; 2996 } 2997 case SCTP_PEER_AUTH_CHUNKS: 2998 { 2999 struct sctp_authchunks *sac; 3000 sctp_auth_chklist_t *chklist = NULL; 3001 size_t size = 0; 3002 3003 SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 3004 SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 3005 3006 if (stcb) { 3007 /* get off the assoc */ 3008 chklist = stcb->asoc.peer_auth_chunks; 3009 /* is there enough space? */ 3010 size = sctp_auth_get_chklist_size(chklist); 3011 if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 3012 error = EINVAL; 3013 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3014 } else { 3015 /* copy in the chunks */ 3016 (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 3017 sac->gauth_number_of_chunks = (uint32_t)size; 3018 *optsize = sizeof(struct sctp_authchunks) + size; 3019 } 3020 SCTP_TCB_UNLOCK(stcb); 3021 } else { 3022 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 3023 error = ENOENT; 3024 } 3025 break; 3026 } 3027 case SCTP_EVENT: 3028 { 3029 struct sctp_event *event; 3030 uint32_t event_type; 3031 3032 SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, *optsize); 3033 SCTP_FIND_STCB(inp, stcb, event->se_assoc_id); 3034 3035 switch (event->se_type) { 3036 case SCTP_ASSOC_CHANGE: 3037 event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT; 3038 break; 3039 case SCTP_PEER_ADDR_CHANGE: 3040 event_type = SCTP_PCB_FLAGS_RECVPADDREVNT; 3041 break; 3042 case SCTP_REMOTE_ERROR: 3043 event_type = SCTP_PCB_FLAGS_RECVPEERERR; 3044 break; 3045 case SCTP_SEND_FAILED: 3046 event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT; 3047 break; 3048 case SCTP_SHUTDOWN_EVENT: 3049 event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT; 3050 break; 3051 case SCTP_ADAPTATION_INDICATION: 3052 event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT; 3053 break; 3054 case SCTP_PARTIAL_DELIVERY_EVENT: 3055 event_type = SCTP_PCB_FLAGS_PDAPIEVNT; 3056 break; 3057 case SCTP_AUTHENTICATION_EVENT: 3058 event_type = SCTP_PCB_FLAGS_AUTHEVNT; 3059 break; 3060 case SCTP_STREAM_RESET_EVENT: 3061 event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT; 3062 break; 3063 case SCTP_SENDER_DRY_EVENT: 3064 event_type = SCTP_PCB_FLAGS_DRYEVNT; 3065 break; 3066 case SCTP_NOTIFICATIONS_STOPPED_EVENT: 3067 event_type = 0; 3068 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 3069 error = ENOTSUP; 3070 break; 3071 case SCTP_ASSOC_RESET_EVENT: 3072 event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT; 3073 break; 3074 case SCTP_STREAM_CHANGE_EVENT: 3075 event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT; 3076 break; 3077 case SCTP_SEND_FAILED_EVENT: 3078 event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT; 3079 break; 3080 default: 3081 event_type = 0; 3082 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3083 error = EINVAL; 3084 break; 3085 } 3086 if (event_type > 0) { 3087 if (stcb) { 3088 event->se_on = sctp_stcb_is_feature_on(inp, stcb, event_type); 3089 } else { 3090 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3091 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3092 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3093 (event->se_assoc_id == SCTP_FUTURE_ASSOC))) { 3094 SCTP_INP_RLOCK(inp); 3095 event->se_on = sctp_is_feature_on(inp, event_type); 3096 SCTP_INP_RUNLOCK(inp); 3097 } else { 3098 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3099 error = EINVAL; 3100 } 3101 } 3102 } 3103 if (stcb != NULL) { 3104 SCTP_TCB_UNLOCK(stcb); 3105 } 3106 if (error == 0) { 3107 *optsize = sizeof(struct sctp_event); 3108 } 3109 break; 3110 } 3111 case SCTP_RECVRCVINFO: 3112 { 3113 int onoff; 3114 3115 if (*optsize < sizeof(int)) { 3116 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3117 error = EINVAL; 3118 } else { 3119 SCTP_INP_RLOCK(inp); 3120 onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 3121 SCTP_INP_RUNLOCK(inp); 3122 } 3123 if (error == 0) { 3124 /* return the option value */ 3125 *(int *)optval = onoff; 3126 *optsize = sizeof(int); 3127 } 3128 break; 3129 } 3130 case SCTP_RECVNXTINFO: 3131 { 3132 int onoff; 3133 3134 if (*optsize < sizeof(int)) { 3135 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3136 error = EINVAL; 3137 } else { 3138 SCTP_INP_RLOCK(inp); 3139 onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 3140 SCTP_INP_RUNLOCK(inp); 3141 } 3142 if (error == 0) { 3143 /* return the option value */ 3144 *(int *)optval = onoff; 3145 *optsize = sizeof(int); 3146 } 3147 break; 3148 } 3149 case SCTP_DEFAULT_SNDINFO: 3150 { 3151 struct sctp_sndinfo *info; 3152 3153 SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, *optsize); 3154 SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id); 3155 3156 if (stcb) { 3157 info->snd_sid = stcb->asoc.def_send.sinfo_stream; 3158 info->snd_flags = stcb->asoc.def_send.sinfo_flags; 3159 info->snd_flags &= 0xfff0; 3160 info->snd_ppid = stcb->asoc.def_send.sinfo_ppid; 3161 info->snd_context = stcb->asoc.def_send.sinfo_context; 3162 SCTP_TCB_UNLOCK(stcb); 3163 } else { 3164 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3165 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3166 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3167 (info->snd_assoc_id == SCTP_FUTURE_ASSOC))) { 3168 SCTP_INP_RLOCK(inp); 3169 info->snd_sid = inp->def_send.sinfo_stream; 3170 info->snd_flags = inp->def_send.sinfo_flags; 3171 info->snd_flags &= 0xfff0; 3172 info->snd_ppid = inp->def_send.sinfo_ppid; 3173 info->snd_context = inp->def_send.sinfo_context; 3174 SCTP_INP_RUNLOCK(inp); 3175 } else { 3176 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3177 error = EINVAL; 3178 } 3179 } 3180 if (error == 0) { 3181 *optsize = sizeof(struct sctp_sndinfo); 3182 } 3183 break; 3184 } 3185 case SCTP_DEFAULT_PRINFO: 3186 { 3187 struct sctp_default_prinfo *info; 3188 3189 SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, *optsize); 3190 SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id); 3191 3192 if (stcb) { 3193 info->pr_policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 3194 info->pr_value = stcb->asoc.def_send.sinfo_timetolive; 3195 SCTP_TCB_UNLOCK(stcb); 3196 } else { 3197 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3198 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3199 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3200 (info->pr_assoc_id == SCTP_FUTURE_ASSOC))) { 3201 SCTP_INP_RLOCK(inp); 3202 info->pr_policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags); 3203 info->pr_value = inp->def_send.sinfo_timetolive; 3204 SCTP_INP_RUNLOCK(inp); 3205 } else { 3206 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3207 error = EINVAL; 3208 } 3209 } 3210 if (error == 0) { 3211 *optsize = sizeof(struct sctp_default_prinfo); 3212 } 3213 break; 3214 } 3215 case SCTP_PEER_ADDR_THLDS: 3216 { 3217 struct sctp_paddrthlds *thlds; 3218 struct sctp_nets *net; 3219 struct sockaddr *addr; 3220 #if defined(INET) && defined(INET6) 3221 struct sockaddr_in sin_store; 3222 #endif 3223 3224 SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize); 3225 SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); 3226 3227 #if defined(INET) && defined(INET6) 3228 if (thlds->spt_address.ss_family == AF_INET6) { 3229 struct sockaddr_in6 *sin6; 3230 3231 sin6 = (struct sockaddr_in6 *)&thlds->spt_address; 3232 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 3233 in6_sin6_2_sin(&sin_store, sin6); 3234 addr = (struct sockaddr *)&sin_store; 3235 } else { 3236 addr = (struct sockaddr *)&thlds->spt_address; 3237 } 3238 } else { 3239 addr = (struct sockaddr *)&thlds->spt_address; 3240 } 3241 #else 3242 addr = (struct sockaddr *)&thlds->spt_address; 3243 #endif 3244 if (stcb != NULL) { 3245 net = sctp_findnet(stcb, addr); 3246 } else { 3247 /* 3248 * We increment here since 3249 * sctp_findassociation_ep_addr() wil do a 3250 * decrement if it finds the stcb as long as 3251 * the locked tcb (last argument) is NOT a 3252 * TCB.. aka NULL. 3253 */ 3254 net = NULL; 3255 SCTP_INP_INCR_REF(inp); 3256 stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL); 3257 if (stcb == NULL) { 3258 SCTP_INP_DECR_REF(inp); 3259 } 3260 } 3261 if ((stcb != NULL) && (net == NULL)) { 3262 #ifdef INET 3263 if (addr->sa_family == AF_INET) { 3264 struct sockaddr_in *sin; 3265 3266 sin = (struct sockaddr_in *)addr; 3267 if (sin->sin_addr.s_addr != INADDR_ANY) { 3268 error = EINVAL; 3269 SCTP_TCB_UNLOCK(stcb); 3270 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3271 break; 3272 } 3273 } else 3274 #endif 3275 #ifdef INET6 3276 if (addr->sa_family == AF_INET6) { 3277 struct sockaddr_in6 *sin6; 3278 3279 sin6 = (struct sockaddr_in6 *)addr; 3280 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 3281 error = EINVAL; 3282 SCTP_TCB_UNLOCK(stcb); 3283 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3284 break; 3285 } 3286 } else 3287 #endif 3288 { 3289 error = EAFNOSUPPORT; 3290 SCTP_TCB_UNLOCK(stcb); 3291 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3292 break; 3293 } 3294 } 3295 3296 if (stcb != NULL) { 3297 if (net != NULL) { 3298 thlds->spt_pathmaxrxt = net->failure_threshold; 3299 thlds->spt_pathpfthld = net->pf_threshold; 3300 thlds->spt_pathcpthld = 0xffff; 3301 } else { 3302 thlds->spt_pathmaxrxt = stcb->asoc.def_net_failure; 3303 thlds->spt_pathpfthld = stcb->asoc.def_net_pf_threshold; 3304 thlds->spt_pathcpthld = 0xffff; 3305 } 3306 thlds->spt_assoc_id = sctp_get_associd(stcb); 3307 SCTP_TCB_UNLOCK(stcb); 3308 } else { 3309 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3310 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3311 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3312 (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC))) { 3313 /* Use endpoint defaults */ 3314 SCTP_INP_RLOCK(inp); 3315 thlds->spt_pathmaxrxt = inp->sctp_ep.def_net_failure; 3316 thlds->spt_pathpfthld = inp->sctp_ep.def_net_pf_threshold; 3317 thlds->spt_pathcpthld = 0xffff; 3318 SCTP_INP_RUNLOCK(inp); 3319 } else { 3320 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3321 error = EINVAL; 3322 } 3323 } 3324 if (error == 0) { 3325 *optsize = sizeof(struct sctp_paddrthlds); 3326 } 3327 break; 3328 } 3329 case SCTP_REMOTE_UDP_ENCAPS_PORT: 3330 { 3331 struct sctp_udpencaps *encaps; 3332 struct sctp_nets *net; 3333 struct sockaddr *addr; 3334 #if defined(INET) && defined(INET6) 3335 struct sockaddr_in sin_store; 3336 #endif 3337 3338 SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize); 3339 SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); 3340 3341 #if defined(INET) && defined(INET6) 3342 if (encaps->sue_address.ss_family == AF_INET6) { 3343 struct sockaddr_in6 *sin6; 3344 3345 sin6 = (struct sockaddr_in6 *)&encaps->sue_address; 3346 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 3347 in6_sin6_2_sin(&sin_store, sin6); 3348 addr = (struct sockaddr *)&sin_store; 3349 } else { 3350 addr = (struct sockaddr *)&encaps->sue_address; 3351 } 3352 } else { 3353 addr = (struct sockaddr *)&encaps->sue_address; 3354 } 3355 #else 3356 addr = (struct sockaddr *)&encaps->sue_address; 3357 #endif 3358 if (stcb) { 3359 net = sctp_findnet(stcb, addr); 3360 } else { 3361 /* 3362 * We increment here since 3363 * sctp_findassociation_ep_addr() wil do a 3364 * decrement if it finds the stcb as long as 3365 * the locked tcb (last argument) is NOT a 3366 * TCB.. aka NULL. 3367 */ 3368 net = NULL; 3369 SCTP_INP_INCR_REF(inp); 3370 stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL); 3371 if (stcb == NULL) { 3372 SCTP_INP_DECR_REF(inp); 3373 } 3374 } 3375 if ((stcb != NULL) && (net == NULL)) { 3376 #ifdef INET 3377 if (addr->sa_family == AF_INET) { 3378 struct sockaddr_in *sin; 3379 3380 sin = (struct sockaddr_in *)addr; 3381 if (sin->sin_addr.s_addr != INADDR_ANY) { 3382 error = EINVAL; 3383 SCTP_TCB_UNLOCK(stcb); 3384 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3385 break; 3386 } 3387 } else 3388 #endif 3389 #ifdef INET6 3390 if (addr->sa_family == AF_INET6) { 3391 struct sockaddr_in6 *sin6; 3392 3393 sin6 = (struct sockaddr_in6 *)addr; 3394 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 3395 error = EINVAL; 3396 SCTP_TCB_UNLOCK(stcb); 3397 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3398 break; 3399 } 3400 } else 3401 #endif 3402 { 3403 error = EAFNOSUPPORT; 3404 SCTP_TCB_UNLOCK(stcb); 3405 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3406 break; 3407 } 3408 } 3409 3410 if (stcb != NULL) { 3411 if (net) { 3412 encaps->sue_port = net->port; 3413 } else { 3414 encaps->sue_port = stcb->asoc.port; 3415 } 3416 SCTP_TCB_UNLOCK(stcb); 3417 } else { 3418 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3419 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3420 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3421 (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC))) { 3422 SCTP_INP_RLOCK(inp); 3423 encaps->sue_port = inp->sctp_ep.port; 3424 SCTP_INP_RUNLOCK(inp); 3425 } else { 3426 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3427 error = EINVAL; 3428 } 3429 } 3430 if (error == 0) { 3431 *optsize = sizeof(struct sctp_udpencaps); 3432 } 3433 break; 3434 } 3435 case SCTP_ECN_SUPPORTED: 3436 { 3437 struct sctp_assoc_value *av; 3438 3439 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3440 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3441 3442 if (stcb) { 3443 av->assoc_value = stcb->asoc.ecn_supported; 3444 SCTP_TCB_UNLOCK(stcb); 3445 } else { 3446 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3447 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3448 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3449 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3450 SCTP_INP_RLOCK(inp); 3451 av->assoc_value = inp->ecn_supported; 3452 SCTP_INP_RUNLOCK(inp); 3453 } else { 3454 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3455 error = EINVAL; 3456 } 3457 } 3458 if (error == 0) { 3459 *optsize = sizeof(struct sctp_assoc_value); 3460 } 3461 break; 3462 } 3463 case SCTP_PR_SUPPORTED: 3464 { 3465 struct sctp_assoc_value *av; 3466 3467 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3468 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3469 3470 if (stcb) { 3471 av->assoc_value = stcb->asoc.prsctp_supported; 3472 SCTP_TCB_UNLOCK(stcb); 3473 } else { 3474 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3475 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3476 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3477 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3478 SCTP_INP_RLOCK(inp); 3479 av->assoc_value = inp->prsctp_supported; 3480 SCTP_INP_RUNLOCK(inp); 3481 } else { 3482 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3483 error = EINVAL; 3484 } 3485 } 3486 if (error == 0) { 3487 *optsize = sizeof(struct sctp_assoc_value); 3488 } 3489 break; 3490 } 3491 case SCTP_AUTH_SUPPORTED: 3492 { 3493 struct sctp_assoc_value *av; 3494 3495 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3496 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3497 3498 if (stcb) { 3499 av->assoc_value = stcb->asoc.auth_supported; 3500 SCTP_TCB_UNLOCK(stcb); 3501 } else { 3502 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3503 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3504 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3505 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3506 SCTP_INP_RLOCK(inp); 3507 av->assoc_value = inp->auth_supported; 3508 SCTP_INP_RUNLOCK(inp); 3509 } else { 3510 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3511 error = EINVAL; 3512 } 3513 } 3514 if (error == 0) { 3515 *optsize = sizeof(struct sctp_assoc_value); 3516 } 3517 break; 3518 } 3519 case SCTP_ASCONF_SUPPORTED: 3520 { 3521 struct sctp_assoc_value *av; 3522 3523 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3524 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3525 3526 if (stcb) { 3527 av->assoc_value = stcb->asoc.asconf_supported; 3528 SCTP_TCB_UNLOCK(stcb); 3529 } else { 3530 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3531 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3532 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3533 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3534 SCTP_INP_RLOCK(inp); 3535 av->assoc_value = inp->asconf_supported; 3536 SCTP_INP_RUNLOCK(inp); 3537 } else { 3538 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3539 error = EINVAL; 3540 } 3541 } 3542 if (error == 0) { 3543 *optsize = sizeof(struct sctp_assoc_value); 3544 } 3545 break; 3546 } 3547 case SCTP_RECONFIG_SUPPORTED: 3548 { 3549 struct sctp_assoc_value *av; 3550 3551 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3552 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3553 3554 if (stcb) { 3555 av->assoc_value = stcb->asoc.reconfig_supported; 3556 SCTP_TCB_UNLOCK(stcb); 3557 } else { 3558 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3559 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3560 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3561 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3562 SCTP_INP_RLOCK(inp); 3563 av->assoc_value = inp->reconfig_supported; 3564 SCTP_INP_RUNLOCK(inp); 3565 } else { 3566 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3567 error = EINVAL; 3568 } 3569 } 3570 if (error == 0) { 3571 *optsize = sizeof(struct sctp_assoc_value); 3572 } 3573 break; 3574 } 3575 case SCTP_NRSACK_SUPPORTED: 3576 { 3577 struct sctp_assoc_value *av; 3578 3579 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3580 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3581 3582 if (stcb) { 3583 av->assoc_value = stcb->asoc.nrsack_supported; 3584 SCTP_TCB_UNLOCK(stcb); 3585 } else { 3586 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3587 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3588 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3589 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3590 SCTP_INP_RLOCK(inp); 3591 av->assoc_value = inp->nrsack_supported; 3592 SCTP_INP_RUNLOCK(inp); 3593 } else { 3594 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3595 error = EINVAL; 3596 } 3597 } 3598 if (error == 0) { 3599 *optsize = sizeof(struct sctp_assoc_value); 3600 } 3601 break; 3602 } 3603 case SCTP_PKTDROP_SUPPORTED: 3604 { 3605 struct sctp_assoc_value *av; 3606 3607 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3608 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3609 3610 if (stcb) { 3611 av->assoc_value = stcb->asoc.pktdrop_supported; 3612 SCTP_TCB_UNLOCK(stcb); 3613 } else { 3614 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3615 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3616 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3617 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3618 SCTP_INP_RLOCK(inp); 3619 av->assoc_value = inp->pktdrop_supported; 3620 SCTP_INP_RUNLOCK(inp); 3621 } else { 3622 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3623 error = EINVAL; 3624 } 3625 } 3626 if (error == 0) { 3627 *optsize = sizeof(struct sctp_assoc_value); 3628 } 3629 break; 3630 } 3631 case SCTP_ENABLE_STREAM_RESET: 3632 { 3633 struct sctp_assoc_value *av; 3634 3635 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3636 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3637 3638 if (stcb) { 3639 av->assoc_value = (uint32_t)stcb->asoc.local_strreset_support; 3640 SCTP_TCB_UNLOCK(stcb); 3641 } else { 3642 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3643 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3644 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3645 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3646 SCTP_INP_RLOCK(inp); 3647 av->assoc_value = (uint32_t)inp->local_strreset_support; 3648 SCTP_INP_RUNLOCK(inp); 3649 } else { 3650 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3651 error = EINVAL; 3652 } 3653 } 3654 if (error == 0) { 3655 *optsize = sizeof(struct sctp_assoc_value); 3656 } 3657 break; 3658 } 3659 case SCTP_PR_STREAM_STATUS: 3660 { 3661 struct sctp_prstatus *sprstat; 3662 uint16_t sid; 3663 uint16_t policy; 3664 3665 SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize); 3666 SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id); 3667 3668 sid = sprstat->sprstat_sid; 3669 policy = sprstat->sprstat_policy; 3670 #if defined(SCTP_DETAILED_STR_STATS) 3671 if ((stcb != NULL) && 3672 (sid < stcb->asoc.streamoutcnt) && 3673 (policy != SCTP_PR_SCTP_NONE) && 3674 ((policy <= SCTP_PR_SCTP_MAX) || 3675 (policy == SCTP_PR_SCTP_ALL))) { 3676 if (policy == SCTP_PR_SCTP_ALL) { 3677 sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; 3678 sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; 3679 } else { 3680 sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy]; 3681 sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy]; 3682 } 3683 #else 3684 if ((stcb != NULL) && 3685 (sid < stcb->asoc.streamoutcnt) && 3686 (policy == SCTP_PR_SCTP_ALL)) { 3687 sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; 3688 sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; 3689 #endif 3690 } else { 3691 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3692 error = EINVAL; 3693 } 3694 if (stcb != NULL) { 3695 SCTP_TCB_UNLOCK(stcb); 3696 } 3697 if (error == 0) { 3698 *optsize = sizeof(struct sctp_prstatus); 3699 } 3700 break; 3701 } 3702 case SCTP_PR_ASSOC_STATUS: 3703 { 3704 struct sctp_prstatus *sprstat; 3705 uint16_t policy; 3706 3707 SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize); 3708 SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id); 3709 3710 policy = sprstat->sprstat_policy; 3711 if ((stcb != NULL) && 3712 (policy != SCTP_PR_SCTP_NONE) && 3713 ((policy <= SCTP_PR_SCTP_MAX) || 3714 (policy == SCTP_PR_SCTP_ALL))) { 3715 if (policy == SCTP_PR_SCTP_ALL) { 3716 sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0]; 3717 sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0]; 3718 } else { 3719 sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[policy]; 3720 sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[policy]; 3721 } 3722 } else { 3723 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3724 error = EINVAL; 3725 } 3726 if (stcb != NULL) { 3727 SCTP_TCB_UNLOCK(stcb); 3728 } 3729 if (error == 0) { 3730 *optsize = sizeof(struct sctp_prstatus); 3731 } 3732 break; 3733 } 3734 case SCTP_MAX_CWND: 3735 { 3736 struct sctp_assoc_value *av; 3737 3738 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 3739 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3740 3741 if (stcb) { 3742 av->assoc_value = stcb->asoc.max_cwnd; 3743 SCTP_TCB_UNLOCK(stcb); 3744 } else { 3745 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3746 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3747 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3748 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3749 SCTP_INP_RLOCK(inp); 3750 av->assoc_value = inp->max_cwnd; 3751 SCTP_INP_RUNLOCK(inp); 3752 } else { 3753 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3754 error = EINVAL; 3755 } 3756 } 3757 if (error == 0) { 3758 *optsize = sizeof(struct sctp_assoc_value); 3759 } 3760 break; 3761 } 3762 default: 3763 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 3764 error = ENOPROTOOPT; 3765 break; 3766 } /* end switch (sopt->sopt_name) */ 3767 if (error) { 3768 *optsize = 0; 3769 } 3770 return (error); 3771 } 3772 3773 static int 3774 sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, 3775 void *p) 3776 { 3777 int error, set_opt; 3778 uint32_t *mopt; 3779 struct sctp_tcb *stcb = NULL; 3780 struct sctp_inpcb *inp = NULL; 3781 uint32_t vrf_id; 3782 3783 if (optval == NULL) { 3784 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3785 return (EINVAL); 3786 } 3787 inp = (struct sctp_inpcb *)so->so_pcb; 3788 if (inp == NULL) { 3789 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3790 return (EINVAL); 3791 } 3792 vrf_id = inp->def_vrf_id; 3793 3794 error = 0; 3795 switch (optname) { 3796 case SCTP_NODELAY: 3797 case SCTP_AUTOCLOSE: 3798 case SCTP_AUTO_ASCONF: 3799 case SCTP_EXPLICIT_EOR: 3800 case SCTP_DISABLE_FRAGMENTS: 3801 case SCTP_USE_EXT_RCVINFO: 3802 case SCTP_I_WANT_MAPPED_V4_ADDR: 3803 /* copy in the option value */ 3804 SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 3805 set_opt = 0; 3806 if (error) 3807 break; 3808 switch (optname) { 3809 case SCTP_DISABLE_FRAGMENTS: 3810 set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT; 3811 break; 3812 case SCTP_AUTO_ASCONF: 3813 /* 3814 * NOTE: we don't really support this flag 3815 */ 3816 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 3817 /* only valid for bound all sockets */ 3818 if ((SCTP_BASE_SYSCTL(sctp_auto_asconf) == 0) && 3819 (*mopt != 0)) { 3820 /* forbidden by admin */ 3821 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EPERM); 3822 return (EPERM); 3823 } 3824 set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF; 3825 } else { 3826 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3827 return (EINVAL); 3828 } 3829 break; 3830 case SCTP_EXPLICIT_EOR: 3831 set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR; 3832 break; 3833 case SCTP_USE_EXT_RCVINFO: 3834 set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO; 3835 break; 3836 case SCTP_I_WANT_MAPPED_V4_ADDR: 3837 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 3838 set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4; 3839 } else { 3840 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3841 return (EINVAL); 3842 } 3843 break; 3844 case SCTP_NODELAY: 3845 set_opt = SCTP_PCB_FLAGS_NODELAY; 3846 break; 3847 case SCTP_AUTOCLOSE: 3848 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3849 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 3850 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3851 return (EINVAL); 3852 } 3853 set_opt = SCTP_PCB_FLAGS_AUTOCLOSE; 3854 /* 3855 * The value is in ticks. Note this does not effect 3856 * old associations, only new ones. 3857 */ 3858 inp->sctp_ep.auto_close_time = sctp_secs_to_ticks(*mopt); 3859 break; 3860 } 3861 SCTP_INP_WLOCK(inp); 3862 if (*mopt != 0) { 3863 sctp_feature_on(inp, set_opt); 3864 } else { 3865 sctp_feature_off(inp, set_opt); 3866 } 3867 SCTP_INP_WUNLOCK(inp); 3868 break; 3869 case SCTP_REUSE_PORT: 3870 { 3871 SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 3872 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 3873 /* Can't set it after we are bound */ 3874 error = EINVAL; 3875 break; 3876 } 3877 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 3878 /* Can't do this for a 1-m socket */ 3879 error = EINVAL; 3880 break; 3881 } 3882 if (optval) 3883 sctp_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 3884 else 3885 sctp_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE); 3886 break; 3887 } 3888 case SCTP_PARTIAL_DELIVERY_POINT: 3889 { 3890 uint32_t *value; 3891 3892 SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize); 3893 if (*value > SCTP_SB_LIMIT_RCV(so)) { 3894 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3895 error = EINVAL; 3896 break; 3897 } 3898 inp->partial_delivery_point = *value; 3899 break; 3900 } 3901 case SCTP_FRAGMENT_INTERLEAVE: 3902 /* not yet until we re-write sctp_recvmsg() */ 3903 { 3904 uint32_t *level; 3905 3906 SCTP_CHECK_AND_CAST(level, optval, uint32_t, optsize); 3907 if (*level == SCTP_FRAG_LEVEL_2) { 3908 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 3909 sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 3910 } else if (*level == SCTP_FRAG_LEVEL_1) { 3911 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 3912 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 3913 } else if (*level == SCTP_FRAG_LEVEL_0) { 3914 sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 3915 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 3916 3917 } else { 3918 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3919 error = EINVAL; 3920 } 3921 break; 3922 } 3923 case SCTP_INTERLEAVING_SUPPORTED: 3924 { 3925 struct sctp_assoc_value *av; 3926 3927 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 3928 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3929 3930 if (stcb) { 3931 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3932 error = EINVAL; 3933 SCTP_TCB_UNLOCK(stcb); 3934 } else { 3935 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3936 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3937 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3938 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 3939 SCTP_INP_WLOCK(inp); 3940 if (av->assoc_value == 0) { 3941 inp->idata_supported = 0; 3942 } else { 3943 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) && 3944 (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS))) { 3945 inp->idata_supported = 1; 3946 } else { 3947 /* 3948 * Must have Frag 3949 * interleave and 3950 * stream interleave 3951 * on 3952 */ 3953 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3954 error = EINVAL; 3955 } 3956 } 3957 SCTP_INP_WUNLOCK(inp); 3958 } else { 3959 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3960 error = EINVAL; 3961 } 3962 } 3963 break; 3964 } 3965 case SCTP_CMT_ON_OFF: 3966 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) { 3967 struct sctp_assoc_value *av; 3968 3969 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 3970 if (av->assoc_value > SCTP_CMT_MAX) { 3971 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3972 error = EINVAL; 3973 break; 3974 } 3975 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3976 if (stcb) { 3977 stcb->asoc.sctp_cmt_on_off = av->assoc_value; 3978 SCTP_TCB_UNLOCK(stcb); 3979 } else { 3980 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3981 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3982 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3983 ((av->assoc_id == SCTP_FUTURE_ASSOC) || 3984 (av->assoc_id == SCTP_ALL_ASSOC)))) { 3985 SCTP_INP_WLOCK(inp); 3986 inp->sctp_cmt_on_off = av->assoc_value; 3987 SCTP_INP_WUNLOCK(inp); 3988 } 3989 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 3990 ((av->assoc_id == SCTP_CURRENT_ASSOC) || 3991 (av->assoc_id == SCTP_ALL_ASSOC))) { 3992 SCTP_INP_RLOCK(inp); 3993 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 3994 SCTP_TCB_LOCK(stcb); 3995 stcb->asoc.sctp_cmt_on_off = av->assoc_value; 3996 SCTP_TCB_UNLOCK(stcb); 3997 } 3998 SCTP_INP_RUNLOCK(inp); 3999 } 4000 } 4001 } else { 4002 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 4003 error = ENOPROTOOPT; 4004 } 4005 break; 4006 case SCTP_PLUGGABLE_CC: 4007 { 4008 struct sctp_assoc_value *av; 4009 struct sctp_nets *net; 4010 4011 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 4012 if ((av->assoc_value != SCTP_CC_RFC2581) && 4013 (av->assoc_value != SCTP_CC_HSTCP) && 4014 (av->assoc_value != SCTP_CC_HTCP) && 4015 (av->assoc_value != SCTP_CC_RTCC)) { 4016 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4017 error = EINVAL; 4018 break; 4019 } 4020 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4021 if (stcb) { 4022 stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value]; 4023 stcb->asoc.congestion_control_module = av->assoc_value; 4024 if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) { 4025 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 4026 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net); 4027 } 4028 } 4029 SCTP_TCB_UNLOCK(stcb); 4030 } else { 4031 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4032 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4033 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4034 ((av->assoc_id == SCTP_FUTURE_ASSOC) || 4035 (av->assoc_id == SCTP_ALL_ASSOC)))) { 4036 SCTP_INP_WLOCK(inp); 4037 inp->sctp_ep.sctp_default_cc_module = av->assoc_value; 4038 SCTP_INP_WUNLOCK(inp); 4039 } 4040 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4041 ((av->assoc_id == SCTP_CURRENT_ASSOC) || 4042 (av->assoc_id == SCTP_ALL_ASSOC))) { 4043 SCTP_INP_RLOCK(inp); 4044 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4045 SCTP_TCB_LOCK(stcb); 4046 stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value]; 4047 stcb->asoc.congestion_control_module = av->assoc_value; 4048 if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) { 4049 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 4050 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net); 4051 } 4052 } 4053 SCTP_TCB_UNLOCK(stcb); 4054 } 4055 SCTP_INP_RUNLOCK(inp); 4056 } 4057 } 4058 break; 4059 } 4060 case SCTP_CC_OPTION: 4061 { 4062 struct sctp_cc_option *cc_opt; 4063 4064 SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, optsize); 4065 SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id); 4066 if (stcb == NULL) { 4067 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4068 (cc_opt->aid_value.assoc_id == SCTP_CURRENT_ASSOC)) { 4069 SCTP_INP_RLOCK(inp); 4070 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4071 SCTP_TCB_LOCK(stcb); 4072 if (stcb->asoc.cc_functions.sctp_cwnd_socket_option) { 4073 (*stcb->asoc.cc_functions.sctp_cwnd_socket_option) (stcb, 1, cc_opt); 4074 } 4075 SCTP_TCB_UNLOCK(stcb); 4076 } 4077 SCTP_INP_RUNLOCK(inp); 4078 } else { 4079 error = EINVAL; 4080 } 4081 } else { 4082 if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) { 4083 error = ENOTSUP; 4084 } else { 4085 error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option) (stcb, 1, 4086 cc_opt); 4087 } 4088 SCTP_TCB_UNLOCK(stcb); 4089 } 4090 break; 4091 } 4092 case SCTP_PLUGGABLE_SS: 4093 { 4094 struct sctp_assoc_value *av; 4095 4096 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 4097 if ((av->assoc_value != SCTP_SS_DEFAULT) && 4098 (av->assoc_value != SCTP_SS_ROUND_ROBIN) && 4099 (av->assoc_value != SCTP_SS_ROUND_ROBIN_PACKET) && 4100 (av->assoc_value != SCTP_SS_PRIORITY) && 4101 (av->assoc_value != SCTP_SS_FAIR_BANDWITH) && 4102 (av->assoc_value != SCTP_SS_FIRST_COME)) { 4103 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4104 error = EINVAL; 4105 break; 4106 } 4107 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4108 if (stcb) { 4109 SCTP_TCB_SEND_LOCK(stcb); 4110 stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1, 1); 4111 stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value]; 4112 stcb->asoc.stream_scheduling_module = av->assoc_value; 4113 stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1); 4114 SCTP_TCB_SEND_UNLOCK(stcb); 4115 SCTP_TCB_UNLOCK(stcb); 4116 } else { 4117 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4118 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4119 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4120 ((av->assoc_id == SCTP_FUTURE_ASSOC) || 4121 (av->assoc_id == SCTP_ALL_ASSOC)))) { 4122 SCTP_INP_WLOCK(inp); 4123 inp->sctp_ep.sctp_default_ss_module = av->assoc_value; 4124 SCTP_INP_WUNLOCK(inp); 4125 } 4126 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4127 ((av->assoc_id == SCTP_CURRENT_ASSOC) || 4128 (av->assoc_id == SCTP_ALL_ASSOC))) { 4129 SCTP_INP_RLOCK(inp); 4130 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4131 SCTP_TCB_LOCK(stcb); 4132 SCTP_TCB_SEND_LOCK(stcb); 4133 stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1, 1); 4134 stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value]; 4135 stcb->asoc.stream_scheduling_module = av->assoc_value; 4136 stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1); 4137 SCTP_TCB_SEND_UNLOCK(stcb); 4138 SCTP_TCB_UNLOCK(stcb); 4139 } 4140 SCTP_INP_RUNLOCK(inp); 4141 } 4142 } 4143 break; 4144 } 4145 case SCTP_SS_VALUE: 4146 { 4147 struct sctp_stream_value *av; 4148 4149 SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize); 4150 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4151 if (stcb) { 4152 if ((av->stream_id >= stcb->asoc.streamoutcnt) || 4153 (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], 4154 av->stream_value) < 0)) { 4155 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4156 error = EINVAL; 4157 } 4158 SCTP_TCB_UNLOCK(stcb); 4159 } else { 4160 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4161 (av->assoc_id == SCTP_CURRENT_ASSOC)) { 4162 SCTP_INP_RLOCK(inp); 4163 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4164 SCTP_TCB_LOCK(stcb); 4165 if (av->stream_id < stcb->asoc.streamoutcnt) { 4166 stcb->asoc.ss_functions.sctp_ss_set_value(stcb, 4167 &stcb->asoc, 4168 &stcb->asoc.strmout[av->stream_id], 4169 av->stream_value); 4170 } 4171 SCTP_TCB_UNLOCK(stcb); 4172 } 4173 SCTP_INP_RUNLOCK(inp); 4174 } else { 4175 /* 4176 * Can't set stream value without 4177 * association 4178 */ 4179 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4180 error = EINVAL; 4181 } 4182 } 4183 break; 4184 } 4185 case SCTP_CLR_STAT_LOG: 4186 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4187 error = EOPNOTSUPP; 4188 break; 4189 case SCTP_CONTEXT: 4190 { 4191 struct sctp_assoc_value *av; 4192 4193 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 4194 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4195 4196 if (stcb) { 4197 stcb->asoc.context = av->assoc_value; 4198 SCTP_TCB_UNLOCK(stcb); 4199 } else { 4200 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4201 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4202 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4203 ((av->assoc_id == SCTP_FUTURE_ASSOC) || 4204 (av->assoc_id == SCTP_ALL_ASSOC)))) { 4205 SCTP_INP_WLOCK(inp); 4206 inp->sctp_context = av->assoc_value; 4207 SCTP_INP_WUNLOCK(inp); 4208 } 4209 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4210 ((av->assoc_id == SCTP_CURRENT_ASSOC) || 4211 (av->assoc_id == SCTP_ALL_ASSOC))) { 4212 SCTP_INP_RLOCK(inp); 4213 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4214 SCTP_TCB_LOCK(stcb); 4215 stcb->asoc.context = av->assoc_value; 4216 SCTP_TCB_UNLOCK(stcb); 4217 } 4218 SCTP_INP_RUNLOCK(inp); 4219 } 4220 } 4221 break; 4222 } 4223 case SCTP_VRF_ID: 4224 { 4225 uint32_t *default_vrfid; 4226 4227 SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, optsize); 4228 if (*default_vrfid > SCTP_MAX_VRF_ID) { 4229 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4230 error = EINVAL; 4231 break; 4232 } 4233 inp->def_vrf_id = *default_vrfid; 4234 break; 4235 } 4236 case SCTP_DEL_VRF_ID: 4237 { 4238 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4239 error = EOPNOTSUPP; 4240 break; 4241 } 4242 case SCTP_ADD_VRF_ID: 4243 { 4244 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4245 error = EOPNOTSUPP; 4246 break; 4247 } 4248 case SCTP_DELAYED_SACK: 4249 { 4250 struct sctp_sack_info *sack; 4251 4252 SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize); 4253 SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 4254 if (sack->sack_delay) { 4255 if (sack->sack_delay > SCTP_MAX_SACK_DELAY) { 4256 error = EINVAL; 4257 if (stcb != NULL) { 4258 SCTP_TCB_UNLOCK(stcb); 4259 } 4260 break; 4261 } 4262 } 4263 if (stcb) { 4264 if (sack->sack_delay) { 4265 stcb->asoc.delayed_ack = sack->sack_delay; 4266 } 4267 if (sack->sack_freq) { 4268 stcb->asoc.sack_freq = sack->sack_freq; 4269 } 4270 SCTP_TCB_UNLOCK(stcb); 4271 } else { 4272 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4273 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4274 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4275 ((sack->sack_assoc_id == SCTP_FUTURE_ASSOC) || 4276 (sack->sack_assoc_id == SCTP_ALL_ASSOC)))) { 4277 SCTP_INP_WLOCK(inp); 4278 if (sack->sack_delay) { 4279 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(sack->sack_delay); 4280 } 4281 if (sack->sack_freq) { 4282 inp->sctp_ep.sctp_sack_freq = sack->sack_freq; 4283 } 4284 SCTP_INP_WUNLOCK(inp); 4285 } 4286 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4287 ((sack->sack_assoc_id == SCTP_CURRENT_ASSOC) || 4288 (sack->sack_assoc_id == SCTP_ALL_ASSOC))) { 4289 SCTP_INP_RLOCK(inp); 4290 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4291 SCTP_TCB_LOCK(stcb); 4292 if (sack->sack_delay) { 4293 stcb->asoc.delayed_ack = sack->sack_delay; 4294 } 4295 if (sack->sack_freq) { 4296 stcb->asoc.sack_freq = sack->sack_freq; 4297 } 4298 SCTP_TCB_UNLOCK(stcb); 4299 } 4300 SCTP_INP_RUNLOCK(inp); 4301 } 4302 } 4303 break; 4304 } 4305 case SCTP_AUTH_CHUNK: 4306 { 4307 struct sctp_authchunk *sauth; 4308 4309 SCTP_CHECK_AND_CAST(sauth, optval, struct sctp_authchunk, optsize); 4310 4311 SCTP_INP_WLOCK(inp); 4312 if (sctp_auth_add_chunk(sauth->sauth_chunk, inp->sctp_ep.local_auth_chunks)) { 4313 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4314 error = EINVAL; 4315 } else { 4316 inp->auth_supported = 1; 4317 } 4318 SCTP_INP_WUNLOCK(inp); 4319 break; 4320 } 4321 case SCTP_AUTH_KEY: 4322 { 4323 struct sctp_authkey *sca; 4324 struct sctp_keyhead *shared_keys; 4325 sctp_sharedkey_t *shared_key; 4326 sctp_key_t *key = NULL; 4327 size_t size; 4328 4329 SCTP_CHECK_AND_CAST(sca, optval, struct sctp_authkey, optsize); 4330 if (sca->sca_keylength == 0) { 4331 size = optsize - sizeof(struct sctp_authkey); 4332 } else { 4333 if (sca->sca_keylength + sizeof(struct sctp_authkey) <= optsize) { 4334 size = sca->sca_keylength; 4335 } else { 4336 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4337 error = EINVAL; 4338 break; 4339 } 4340 } 4341 SCTP_FIND_STCB(inp, stcb, sca->sca_assoc_id); 4342 4343 if (stcb) { 4344 shared_keys = &stcb->asoc.shared_keys; 4345 /* clear the cached keys for this key id */ 4346 sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 4347 /* 4348 * create the new shared key and 4349 * insert/replace it 4350 */ 4351 if (size > 0) { 4352 key = sctp_set_key(sca->sca_key, (uint32_t)size); 4353 if (key == NULL) { 4354 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 4355 error = ENOMEM; 4356 SCTP_TCB_UNLOCK(stcb); 4357 break; 4358 } 4359 } 4360 shared_key = sctp_alloc_sharedkey(); 4361 if (shared_key == NULL) { 4362 sctp_free_key(key); 4363 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 4364 error = ENOMEM; 4365 SCTP_TCB_UNLOCK(stcb); 4366 break; 4367 } 4368 shared_key->key = key; 4369 shared_key->keyid = sca->sca_keynumber; 4370 error = sctp_insert_sharedkey(shared_keys, shared_key); 4371 SCTP_TCB_UNLOCK(stcb); 4372 } else { 4373 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4374 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4375 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4376 ((sca->sca_assoc_id == SCTP_FUTURE_ASSOC) || 4377 (sca->sca_assoc_id == SCTP_ALL_ASSOC)))) { 4378 SCTP_INP_WLOCK(inp); 4379 shared_keys = &inp->sctp_ep.shared_keys; 4380 /* 4381 * clear the cached keys on all 4382 * assocs for this key id 4383 */ 4384 sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber); 4385 /* 4386 * create the new shared key and 4387 * insert/replace it 4388 */ 4389 if (size > 0) { 4390 key = sctp_set_key(sca->sca_key, (uint32_t)size); 4391 if (key == NULL) { 4392 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 4393 error = ENOMEM; 4394 SCTP_INP_WUNLOCK(inp); 4395 break; 4396 } 4397 } 4398 shared_key = sctp_alloc_sharedkey(); 4399 if (shared_key == NULL) { 4400 sctp_free_key(key); 4401 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 4402 error = ENOMEM; 4403 SCTP_INP_WUNLOCK(inp); 4404 break; 4405 } 4406 shared_key->key = key; 4407 shared_key->keyid = sca->sca_keynumber; 4408 error = sctp_insert_sharedkey(shared_keys, shared_key); 4409 SCTP_INP_WUNLOCK(inp); 4410 } 4411 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4412 ((sca->sca_assoc_id == SCTP_CURRENT_ASSOC) || 4413 (sca->sca_assoc_id == SCTP_ALL_ASSOC))) { 4414 SCTP_INP_RLOCK(inp); 4415 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4416 SCTP_TCB_LOCK(stcb); 4417 shared_keys = &stcb->asoc.shared_keys; 4418 /* 4419 * clear the cached keys for 4420 * this key id 4421 */ 4422 sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 4423 /* 4424 * create the new shared key 4425 * and insert/replace it 4426 */ 4427 if (size > 0) { 4428 key = sctp_set_key(sca->sca_key, (uint32_t)size); 4429 if (key == NULL) { 4430 SCTP_TCB_UNLOCK(stcb); 4431 continue; 4432 } 4433 } 4434 shared_key = sctp_alloc_sharedkey(); 4435 if (shared_key == NULL) { 4436 sctp_free_key(key); 4437 SCTP_TCB_UNLOCK(stcb); 4438 continue; 4439 } 4440 shared_key->key = key; 4441 shared_key->keyid = sca->sca_keynumber; 4442 error = sctp_insert_sharedkey(shared_keys, shared_key); 4443 SCTP_TCB_UNLOCK(stcb); 4444 } 4445 SCTP_INP_RUNLOCK(inp); 4446 } 4447 } 4448 break; 4449 } 4450 case SCTP_HMAC_IDENT: 4451 { 4452 struct sctp_hmacalgo *shmac; 4453 sctp_hmaclist_t *hmaclist; 4454 uint16_t hmacid; 4455 uint32_t i; 4456 4457 SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize); 4458 if ((optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) || 4459 (shmac->shmac_number_of_idents > 0xffff)) { 4460 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4461 error = EINVAL; 4462 break; 4463 } 4464 4465 hmaclist = sctp_alloc_hmaclist((uint16_t)shmac->shmac_number_of_idents); 4466 if (hmaclist == NULL) { 4467 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 4468 error = ENOMEM; 4469 break; 4470 } 4471 for (i = 0; i < shmac->shmac_number_of_idents; i++) { 4472 hmacid = shmac->shmac_idents[i]; 4473 if (sctp_auth_add_hmacid(hmaclist, hmacid)) { 4474 /* invalid HMACs were found */ ; 4475 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4476 error = EINVAL; 4477 sctp_free_hmaclist(hmaclist); 4478 goto sctp_set_hmac_done; 4479 } 4480 } 4481 for (i = 0; i < hmaclist->num_algo; i++) { 4482 if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) { 4483 /* already in list */ 4484 break; 4485 } 4486 } 4487 if (i == hmaclist->num_algo) { 4488 /* not found in list */ 4489 sctp_free_hmaclist(hmaclist); 4490 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4491 error = EINVAL; 4492 break; 4493 } 4494 /* set it on the endpoint */ 4495 SCTP_INP_WLOCK(inp); 4496 if (inp->sctp_ep.local_hmacs) 4497 sctp_free_hmaclist(inp->sctp_ep.local_hmacs); 4498 inp->sctp_ep.local_hmacs = hmaclist; 4499 SCTP_INP_WUNLOCK(inp); 4500 sctp_set_hmac_done: 4501 break; 4502 } 4503 case SCTP_AUTH_ACTIVE_KEY: 4504 { 4505 struct sctp_authkeyid *scact; 4506 4507 SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, optsize); 4508 SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 4509 4510 /* set the active key on the right place */ 4511 if (stcb) { 4512 /* set the active key on the assoc */ 4513 if (sctp_auth_setactivekey(stcb, 4514 scact->scact_keynumber)) { 4515 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 4516 SCTP_FROM_SCTP_USRREQ, 4517 EINVAL); 4518 error = EINVAL; 4519 } 4520 SCTP_TCB_UNLOCK(stcb); 4521 } else { 4522 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4523 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4524 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4525 ((scact->scact_assoc_id == SCTP_FUTURE_ASSOC) || 4526 (scact->scact_assoc_id == SCTP_ALL_ASSOC)))) { 4527 SCTP_INP_WLOCK(inp); 4528 if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber)) { 4529 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4530 error = EINVAL; 4531 } 4532 SCTP_INP_WUNLOCK(inp); 4533 } 4534 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4535 ((scact->scact_assoc_id == SCTP_CURRENT_ASSOC) || 4536 (scact->scact_assoc_id == SCTP_ALL_ASSOC))) { 4537 SCTP_INP_RLOCK(inp); 4538 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4539 SCTP_TCB_LOCK(stcb); 4540 sctp_auth_setactivekey(stcb, scact->scact_keynumber); 4541 SCTP_TCB_UNLOCK(stcb); 4542 } 4543 SCTP_INP_RUNLOCK(inp); 4544 } 4545 } 4546 break; 4547 } 4548 case SCTP_AUTH_DELETE_KEY: 4549 { 4550 struct sctp_authkeyid *scdel; 4551 4552 SCTP_CHECK_AND_CAST(scdel, optval, struct sctp_authkeyid, optsize); 4553 SCTP_FIND_STCB(inp, stcb, scdel->scact_assoc_id); 4554 4555 /* delete the key from the right place */ 4556 if (stcb) { 4557 if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber)) { 4558 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4559 error = EINVAL; 4560 } 4561 SCTP_TCB_UNLOCK(stcb); 4562 } else { 4563 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4564 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4565 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4566 ((scdel->scact_assoc_id == SCTP_FUTURE_ASSOC) || 4567 (scdel->scact_assoc_id == SCTP_ALL_ASSOC)))) { 4568 SCTP_INP_WLOCK(inp); 4569 if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber)) { 4570 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4571 error = EINVAL; 4572 } 4573 SCTP_INP_WUNLOCK(inp); 4574 } 4575 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4576 ((scdel->scact_assoc_id == SCTP_CURRENT_ASSOC) || 4577 (scdel->scact_assoc_id == SCTP_ALL_ASSOC))) { 4578 SCTP_INP_RLOCK(inp); 4579 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4580 SCTP_TCB_LOCK(stcb); 4581 sctp_delete_sharedkey(stcb, scdel->scact_keynumber); 4582 SCTP_TCB_UNLOCK(stcb); 4583 } 4584 SCTP_INP_RUNLOCK(inp); 4585 } 4586 } 4587 break; 4588 } 4589 case SCTP_AUTH_DEACTIVATE_KEY: 4590 { 4591 struct sctp_authkeyid *keyid; 4592 4593 SCTP_CHECK_AND_CAST(keyid, optval, struct sctp_authkeyid, optsize); 4594 SCTP_FIND_STCB(inp, stcb, keyid->scact_assoc_id); 4595 4596 /* deactivate the key from the right place */ 4597 if (stcb) { 4598 if (sctp_deact_sharedkey(stcb, keyid->scact_keynumber)) { 4599 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4600 error = EINVAL; 4601 } 4602 SCTP_TCB_UNLOCK(stcb); 4603 } else { 4604 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4605 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4606 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4607 ((keyid->scact_assoc_id == SCTP_FUTURE_ASSOC) || 4608 (keyid->scact_assoc_id == SCTP_ALL_ASSOC)))) { 4609 SCTP_INP_WLOCK(inp); 4610 if (sctp_deact_sharedkey_ep(inp, keyid->scact_keynumber)) { 4611 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4612 error = EINVAL; 4613 } 4614 SCTP_INP_WUNLOCK(inp); 4615 } 4616 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4617 ((keyid->scact_assoc_id == SCTP_CURRENT_ASSOC) || 4618 (keyid->scact_assoc_id == SCTP_ALL_ASSOC))) { 4619 SCTP_INP_RLOCK(inp); 4620 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4621 SCTP_TCB_LOCK(stcb); 4622 sctp_deact_sharedkey(stcb, keyid->scact_keynumber); 4623 SCTP_TCB_UNLOCK(stcb); 4624 } 4625 SCTP_INP_RUNLOCK(inp); 4626 } 4627 } 4628 break; 4629 } 4630 case SCTP_ENABLE_STREAM_RESET: 4631 { 4632 struct sctp_assoc_value *av; 4633 4634 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 4635 if (av->assoc_value & (~SCTP_ENABLE_VALUE_MASK)) { 4636 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4637 error = EINVAL; 4638 break; 4639 } 4640 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4641 if (stcb) { 4642 stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value; 4643 SCTP_TCB_UNLOCK(stcb); 4644 } else { 4645 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4646 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4647 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4648 ((av->assoc_id == SCTP_FUTURE_ASSOC) || 4649 (av->assoc_id == SCTP_ALL_ASSOC)))) { 4650 SCTP_INP_WLOCK(inp); 4651 inp->local_strreset_support = (uint8_t)av->assoc_value; 4652 SCTP_INP_WUNLOCK(inp); 4653 } 4654 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 4655 ((av->assoc_id == SCTP_CURRENT_ASSOC) || 4656 (av->assoc_id == SCTP_ALL_ASSOC))) { 4657 SCTP_INP_RLOCK(inp); 4658 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4659 SCTP_TCB_LOCK(stcb); 4660 stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value; 4661 SCTP_TCB_UNLOCK(stcb); 4662 } 4663 SCTP_INP_RUNLOCK(inp); 4664 } 4665 4666 } 4667 break; 4668 } 4669 case SCTP_RESET_STREAMS: 4670 { 4671 struct sctp_reset_streams *strrst; 4672 int i, send_out = 0; 4673 int send_in = 0; 4674 4675 SCTP_CHECK_AND_CAST(strrst, optval, struct sctp_reset_streams, optsize); 4676 SCTP_FIND_STCB(inp, stcb, strrst->srs_assoc_id); 4677 if (stcb == NULL) { 4678 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 4679 error = ENOENT; 4680 break; 4681 } 4682 if (stcb->asoc.reconfig_supported == 0) { 4683 /* 4684 * Peer does not support the chunk type. 4685 */ 4686 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4687 error = EOPNOTSUPP; 4688 SCTP_TCB_UNLOCK(stcb); 4689 break; 4690 } 4691 if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) { 4692 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4693 error = EINVAL; 4694 SCTP_TCB_UNLOCK(stcb); 4695 break; 4696 } 4697 if (sizeof(struct sctp_reset_streams) + 4698 strrst->srs_number_streams * sizeof(uint16_t) > optsize) { 4699 error = EINVAL; 4700 SCTP_TCB_UNLOCK(stcb); 4701 break; 4702 } 4703 if (strrst->srs_flags & SCTP_STREAM_RESET_INCOMING) { 4704 send_in = 1; 4705 if (stcb->asoc.stream_reset_outstanding) { 4706 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 4707 error = EALREADY; 4708 SCTP_TCB_UNLOCK(stcb); 4709 break; 4710 } 4711 } 4712 if (strrst->srs_flags & SCTP_STREAM_RESET_OUTGOING) { 4713 send_out = 1; 4714 } 4715 if ((strrst->srs_number_streams > SCTP_MAX_STREAMS_AT_ONCE_RESET) && send_in) { 4716 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 4717 error = ENOMEM; 4718 SCTP_TCB_UNLOCK(stcb); 4719 break; 4720 } 4721 if ((send_in == 0) && (send_out == 0)) { 4722 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4723 error = EINVAL; 4724 SCTP_TCB_UNLOCK(stcb); 4725 break; 4726 } 4727 for (i = 0; i < strrst->srs_number_streams; i++) { 4728 if ((send_in) && 4729 (strrst->srs_stream_list[i] >= stcb->asoc.streamincnt)) { 4730 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4731 error = EINVAL; 4732 break; 4733 } 4734 if ((send_out) && 4735 (strrst->srs_stream_list[i] >= stcb->asoc.streamoutcnt)) { 4736 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4737 error = EINVAL; 4738 break; 4739 } 4740 } 4741 if (error) { 4742 SCTP_TCB_UNLOCK(stcb); 4743 break; 4744 } 4745 if (send_out) { 4746 int cnt; 4747 uint16_t strm; 4748 4749 if (strrst->srs_number_streams) { 4750 for (i = 0, cnt = 0; i < strrst->srs_number_streams; i++) { 4751 strm = strrst->srs_stream_list[i]; 4752 if (stcb->asoc.strmout[strm].state == SCTP_STREAM_OPEN) { 4753 stcb->asoc.strmout[strm].state = SCTP_STREAM_RESET_PENDING; 4754 cnt++; 4755 } 4756 } 4757 } else { 4758 /* Its all */ 4759 for (i = 0, cnt = 0; i < stcb->asoc.streamoutcnt; i++) { 4760 if (stcb->asoc.strmout[i].state == SCTP_STREAM_OPEN) { 4761 stcb->asoc.strmout[i].state = SCTP_STREAM_RESET_PENDING; 4762 cnt++; 4763 } 4764 } 4765 } 4766 } 4767 if (send_in) { 4768 error = sctp_send_str_reset_req(stcb, strrst->srs_number_streams, 4769 strrst->srs_stream_list, 4770 send_in, 0, 0, 0, 0, 0); 4771 } else { 4772 error = sctp_send_stream_reset_out_if_possible(stcb, SCTP_SO_LOCKED); 4773 } 4774 if (error == 0) { 4775 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 4776 } else { 4777 /* 4778 * For outgoing streams don't report any 4779 * problems in sending the request to the 4780 * application. XXX: Double check resetting 4781 * incoming streams. 4782 */ 4783 error = 0; 4784 } 4785 SCTP_TCB_UNLOCK(stcb); 4786 break; 4787 } 4788 case SCTP_ADD_STREAMS: 4789 { 4790 struct sctp_add_streams *stradd; 4791 uint8_t addstream = 0; 4792 uint16_t add_o_strmcnt = 0; 4793 uint16_t add_i_strmcnt = 0; 4794 4795 SCTP_CHECK_AND_CAST(stradd, optval, struct sctp_add_streams, optsize); 4796 SCTP_FIND_STCB(inp, stcb, stradd->sas_assoc_id); 4797 if (stcb == NULL) { 4798 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 4799 error = ENOENT; 4800 break; 4801 } 4802 if (stcb->asoc.reconfig_supported == 0) { 4803 /* 4804 * Peer does not support the chunk type. 4805 */ 4806 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4807 error = EOPNOTSUPP; 4808 SCTP_TCB_UNLOCK(stcb); 4809 break; 4810 } 4811 if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) { 4812 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4813 error = EINVAL; 4814 SCTP_TCB_UNLOCK(stcb); 4815 break; 4816 } 4817 if (stcb->asoc.stream_reset_outstanding) { 4818 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 4819 error = EALREADY; 4820 SCTP_TCB_UNLOCK(stcb); 4821 break; 4822 } 4823 if ((stradd->sas_outstrms == 0) && 4824 (stradd->sas_instrms == 0)) { 4825 error = EINVAL; 4826 goto skip_stuff; 4827 } 4828 if (stradd->sas_outstrms) { 4829 addstream = 1; 4830 /* We allocate here */ 4831 add_o_strmcnt = stradd->sas_outstrms; 4832 if ((((int)add_o_strmcnt) + ((int)stcb->asoc.streamoutcnt)) > 0x0000ffff) { 4833 /* You can't have more than 64k */ 4834 error = EINVAL; 4835 goto skip_stuff; 4836 } 4837 } 4838 if (stradd->sas_instrms) { 4839 int cnt; 4840 4841 addstream |= 2; 4842 /* 4843 * We allocate inside 4844 * sctp_send_str_reset_req() 4845 */ 4846 add_i_strmcnt = stradd->sas_instrms; 4847 cnt = add_i_strmcnt; 4848 cnt += stcb->asoc.streamincnt; 4849 if (cnt > 0x0000ffff) { 4850 /* You can't have more than 64k */ 4851 error = EINVAL; 4852 goto skip_stuff; 4853 } 4854 if (cnt > (int)stcb->asoc.max_inbound_streams) { 4855 /* More than you are allowed */ 4856 error = EINVAL; 4857 goto skip_stuff; 4858 } 4859 } 4860 error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, addstream, add_o_strmcnt, add_i_strmcnt, 0); 4861 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 4862 skip_stuff: 4863 SCTP_TCB_UNLOCK(stcb); 4864 break; 4865 } 4866 case SCTP_RESET_ASSOC: 4867 { 4868 int i; 4869 uint32_t *value; 4870 4871 SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize); 4872 SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t)*value); 4873 if (stcb == NULL) { 4874 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 4875 error = ENOENT; 4876 break; 4877 } 4878 if (stcb->asoc.reconfig_supported == 0) { 4879 /* 4880 * Peer does not support the chunk type. 4881 */ 4882 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4883 error = EOPNOTSUPP; 4884 SCTP_TCB_UNLOCK(stcb); 4885 break; 4886 } 4887 if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) { 4888 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4889 error = EINVAL; 4890 SCTP_TCB_UNLOCK(stcb); 4891 break; 4892 } 4893 if (stcb->asoc.stream_reset_outstanding) { 4894 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 4895 error = EALREADY; 4896 SCTP_TCB_UNLOCK(stcb); 4897 break; 4898 } 4899 /* 4900 * Is there any data pending in the send or sent 4901 * queues? 4902 */ 4903 if (!TAILQ_EMPTY(&stcb->asoc.send_queue) || 4904 !TAILQ_EMPTY(&stcb->asoc.sent_queue)) { 4905 busy_out: 4906 error = EBUSY; 4907 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 4908 SCTP_TCB_UNLOCK(stcb); 4909 break; 4910 } 4911 /* Do any streams have data queued? */ 4912 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { 4913 if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) { 4914 goto busy_out; 4915 } 4916 } 4917 error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 1, 0, 0, 0, 0); 4918 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 4919 SCTP_TCB_UNLOCK(stcb); 4920 break; 4921 } 4922 case SCTP_CONNECT_X: 4923 if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 4924 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4925 error = EINVAL; 4926 break; 4927 } 4928 error = sctp_do_connect_x(so, inp, optval, optsize, p, 0); 4929 break; 4930 case SCTP_CONNECT_X_DELAYED: 4931 if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 4932 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4933 error = EINVAL; 4934 break; 4935 } 4936 error = sctp_do_connect_x(so, inp, optval, optsize, p, 1); 4937 break; 4938 case SCTP_CONNECT_X_COMPLETE: 4939 { 4940 struct sockaddr *sa; 4941 4942 /* FIXME MT: check correct? */ 4943 SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize); 4944 4945 /* find tcb */ 4946 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4947 SCTP_INP_RLOCK(inp); 4948 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4949 if (stcb) { 4950 SCTP_TCB_LOCK(stcb); 4951 } 4952 SCTP_INP_RUNLOCK(inp); 4953 } else { 4954 /* 4955 * We increment here since 4956 * sctp_findassociation_ep_addr() wil do a 4957 * decrement if it finds the stcb as long as 4958 * the locked tcb (last argument) is NOT a 4959 * TCB.. aka NULL. 4960 */ 4961 SCTP_INP_INCR_REF(inp); 4962 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL); 4963 if (stcb == NULL) { 4964 SCTP_INP_DECR_REF(inp); 4965 } 4966 } 4967 4968 if (stcb == NULL) { 4969 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 4970 error = ENOENT; 4971 break; 4972 } 4973 if (stcb->asoc.delayed_connection == 1) { 4974 stcb->asoc.delayed_connection = 0; 4975 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 4976 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, 4977 stcb->asoc.primary_destination, 4978 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8); 4979 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 4980 } else { 4981 /* 4982 * already expired or did not use delayed 4983 * connectx 4984 */ 4985 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 4986 error = EALREADY; 4987 } 4988 SCTP_TCB_UNLOCK(stcb); 4989 break; 4990 } 4991 case SCTP_MAX_BURST: 4992 { 4993 struct sctp_assoc_value *av; 4994 4995 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 4996 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4997 4998 if (stcb) { 4999 stcb->asoc.max_burst = av->assoc_value; 5000 SCTP_TCB_UNLOCK(stcb); 5001 } else { 5002 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5003 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 5004 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5005 ((av->assoc_id == SCTP_FUTURE_ASSOC) || 5006 (av->assoc_id == SCTP_ALL_ASSOC)))) { 5007 SCTP_INP_WLOCK(inp); 5008 inp->sctp_ep.max_burst = av->assoc_value; 5009 SCTP_INP_WUNLOCK(inp); 5010 } 5011 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5012 ((av->assoc_id == SCTP_CURRENT_ASSOC) || 5013 (av->assoc_id == SCTP_ALL_ASSOC))) { 5014 SCTP_INP_RLOCK(inp); 5015 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 5016 SCTP_TCB_LOCK(stcb); 5017 stcb->asoc.max_burst = av->assoc_value; 5018 SCTP_TCB_UNLOCK(stcb); 5019 } 5020 SCTP_INP_RUNLOCK(inp); 5021 } 5022 } 5023 break; 5024 } 5025 case SCTP_MAXSEG: 5026 { 5027 struct sctp_assoc_value *av; 5028 int ovh; 5029 5030 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 5031 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 5032 5033 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 5034 ovh = SCTP_MED_OVERHEAD; 5035 } else { 5036 ovh = SCTP_MED_V4_OVERHEAD; 5037 } 5038 if (stcb) { 5039 if (av->assoc_value) { 5040 stcb->asoc.sctp_frag_point = (av->assoc_value + ovh); 5041 } else { 5042 stcb->asoc.sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 5043 } 5044 SCTP_TCB_UNLOCK(stcb); 5045 } else { 5046 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5047 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 5048 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5049 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 5050 SCTP_INP_WLOCK(inp); 5051 /* 5052 * FIXME MT: I think this is not in 5053 * tune with the API ID 5054 */ 5055 if (av->assoc_value) { 5056 inp->sctp_frag_point = (av->assoc_value + ovh); 5057 } else { 5058 inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 5059 } 5060 SCTP_INP_WUNLOCK(inp); 5061 } else { 5062 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5063 error = EINVAL; 5064 } 5065 } 5066 break; 5067 } 5068 case SCTP_EVENTS: 5069 { 5070 struct sctp_event_subscribe *events; 5071 5072 SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, optsize); 5073 5074 SCTP_INP_WLOCK(inp); 5075 if (events->sctp_data_io_event) { 5076 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 5077 } else { 5078 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 5079 } 5080 5081 if (events->sctp_association_event) { 5082 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 5083 } else { 5084 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 5085 } 5086 5087 if (events->sctp_address_event) { 5088 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 5089 } else { 5090 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 5091 } 5092 5093 if (events->sctp_send_failure_event) { 5094 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 5095 } else { 5096 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 5097 } 5098 5099 if (events->sctp_peer_error_event) { 5100 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR); 5101 } else { 5102 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR); 5103 } 5104 5105 if (events->sctp_shutdown_event) { 5106 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 5107 } else { 5108 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 5109 } 5110 5111 if (events->sctp_partial_delivery_event) { 5112 sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 5113 } else { 5114 sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 5115 } 5116 5117 if (events->sctp_adaptation_layer_event) { 5118 sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 5119 } else { 5120 sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 5121 } 5122 5123 if (events->sctp_authentication_event) { 5124 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT); 5125 } else { 5126 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT); 5127 } 5128 5129 if (events->sctp_sender_dry_event) { 5130 sctp_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT); 5131 } else { 5132 sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT); 5133 } 5134 5135 if (events->sctp_stream_reset_event) { 5136 sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 5137 } else { 5138 sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 5139 } 5140 SCTP_INP_WUNLOCK(inp); 5141 5142 SCTP_INP_RLOCK(inp); 5143 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 5144 SCTP_TCB_LOCK(stcb); 5145 if (events->sctp_association_event) { 5146 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT); 5147 } else { 5148 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT); 5149 } 5150 if (events->sctp_address_event) { 5151 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT); 5152 } else { 5153 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT); 5154 } 5155 if (events->sctp_send_failure_event) { 5156 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 5157 } else { 5158 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 5159 } 5160 if (events->sctp_peer_error_event) { 5161 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR); 5162 } else { 5163 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR); 5164 } 5165 if (events->sctp_shutdown_event) { 5166 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 5167 } else { 5168 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 5169 } 5170 if (events->sctp_partial_delivery_event) { 5171 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT); 5172 } else { 5173 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT); 5174 } 5175 if (events->sctp_adaptation_layer_event) { 5176 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 5177 } else { 5178 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 5179 } 5180 if (events->sctp_authentication_event) { 5181 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT); 5182 } else { 5183 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT); 5184 } 5185 if (events->sctp_sender_dry_event) { 5186 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT); 5187 } else { 5188 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT); 5189 } 5190 if (events->sctp_stream_reset_event) { 5191 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 5192 } else { 5193 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 5194 } 5195 SCTP_TCB_UNLOCK(stcb); 5196 } 5197 /* 5198 * Send up the sender dry event only for 1-to-1 5199 * style sockets. 5200 */ 5201 if (events->sctp_sender_dry_event) { 5202 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5203 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 5204 stcb = LIST_FIRST(&inp->sctp_asoc_list); 5205 if (stcb) { 5206 SCTP_TCB_LOCK(stcb); 5207 if (TAILQ_EMPTY(&stcb->asoc.send_queue) && 5208 TAILQ_EMPTY(&stcb->asoc.sent_queue) && 5209 (stcb->asoc.stream_queue_cnt == 0)) { 5210 sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED); 5211 } 5212 SCTP_TCB_UNLOCK(stcb); 5213 } 5214 } 5215 } 5216 SCTP_INP_RUNLOCK(inp); 5217 break; 5218 } 5219 case SCTP_ADAPTATION_LAYER: 5220 { 5221 struct sctp_setadaptation *adap_bits; 5222 5223 SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize); 5224 SCTP_INP_WLOCK(inp); 5225 inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind; 5226 inp->sctp_ep.adaptation_layer_indicator_provided = 1; 5227 SCTP_INP_WUNLOCK(inp); 5228 break; 5229 } 5230 #ifdef SCTP_DEBUG 5231 case SCTP_SET_INITIAL_DBG_SEQ: 5232 { 5233 uint32_t *vvv; 5234 5235 SCTP_CHECK_AND_CAST(vvv, optval, uint32_t, optsize); 5236 SCTP_INP_WLOCK(inp); 5237 inp->sctp_ep.initial_sequence_debug = *vvv; 5238 SCTP_INP_WUNLOCK(inp); 5239 break; 5240 } 5241 #endif 5242 case SCTP_DEFAULT_SEND_PARAM: 5243 { 5244 struct sctp_sndrcvinfo *s_info; 5245 5246 SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, optsize); 5247 SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 5248 5249 if (stcb) { 5250 if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) { 5251 memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send))); 5252 } else { 5253 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5254 error = EINVAL; 5255 } 5256 SCTP_TCB_UNLOCK(stcb); 5257 } else { 5258 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5259 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 5260 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5261 ((s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC) || 5262 (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC)))) { 5263 SCTP_INP_WLOCK(inp); 5264 memcpy(&inp->def_send, s_info, min(optsize, sizeof(inp->def_send))); 5265 SCTP_INP_WUNLOCK(inp); 5266 } 5267 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5268 ((s_info->sinfo_assoc_id == SCTP_CURRENT_ASSOC) || 5269 (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC))) { 5270 SCTP_INP_RLOCK(inp); 5271 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 5272 SCTP_TCB_LOCK(stcb); 5273 if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) { 5274 memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send))); 5275 } 5276 SCTP_TCB_UNLOCK(stcb); 5277 } 5278 SCTP_INP_RUNLOCK(inp); 5279 } 5280 } 5281 break; 5282 } 5283 case SCTP_PEER_ADDR_PARAMS: 5284 { 5285 struct sctp_paddrparams *paddrp; 5286 struct sctp_nets *net; 5287 struct sockaddr *addr; 5288 #if defined(INET) && defined(INET6) 5289 struct sockaddr_in sin_store; 5290 #endif 5291 5292 SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize); 5293 SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 5294 5295 #if defined(INET) && defined(INET6) 5296 if (paddrp->spp_address.ss_family == AF_INET6) { 5297 struct sockaddr_in6 *sin6; 5298 5299 sin6 = (struct sockaddr_in6 *)&paddrp->spp_address; 5300 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 5301 in6_sin6_2_sin(&sin_store, sin6); 5302 addr = (struct sockaddr *)&sin_store; 5303 } else { 5304 addr = (struct sockaddr *)&paddrp->spp_address; 5305 } 5306 } else { 5307 addr = (struct sockaddr *)&paddrp->spp_address; 5308 } 5309 #else 5310 addr = (struct sockaddr *)&paddrp->spp_address; 5311 #endif 5312 if (stcb != NULL) { 5313 net = sctp_findnet(stcb, addr); 5314 } else { 5315 /* 5316 * We increment here since 5317 * sctp_findassociation_ep_addr() wil do a 5318 * decrement if it finds the stcb as long as 5319 * the locked tcb (last argument) is NOT a 5320 * TCB.. aka NULL. 5321 */ 5322 net = NULL; 5323 SCTP_INP_INCR_REF(inp); 5324 stcb = sctp_findassociation_ep_addr(&inp, addr, 5325 &net, NULL, NULL); 5326 if (stcb == NULL) { 5327 SCTP_INP_DECR_REF(inp); 5328 } 5329 } 5330 if ((stcb != NULL) && (net == NULL)) { 5331 #ifdef INET 5332 if (addr->sa_family == AF_INET) { 5333 5334 struct sockaddr_in *sin; 5335 5336 sin = (struct sockaddr_in *)addr; 5337 if (sin->sin_addr.s_addr != INADDR_ANY) { 5338 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5339 SCTP_TCB_UNLOCK(stcb); 5340 error = EINVAL; 5341 break; 5342 } 5343 } else 5344 #endif 5345 #ifdef INET6 5346 if (addr->sa_family == AF_INET6) { 5347 struct sockaddr_in6 *sin6; 5348 5349 sin6 = (struct sockaddr_in6 *)addr; 5350 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 5351 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5352 SCTP_TCB_UNLOCK(stcb); 5353 error = EINVAL; 5354 break; 5355 } 5356 } else 5357 #endif 5358 { 5359 error = EAFNOSUPPORT; 5360 SCTP_TCB_UNLOCK(stcb); 5361 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 5362 break; 5363 } 5364 } 5365 /* sanity checks */ 5366 if ((paddrp->spp_flags & SPP_HB_ENABLE) && (paddrp->spp_flags & SPP_HB_DISABLE)) { 5367 if (stcb) 5368 SCTP_TCB_UNLOCK(stcb); 5369 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5370 return (EINVAL); 5371 } 5372 5373 if ((paddrp->spp_flags & SPP_PMTUD_ENABLE) && (paddrp->spp_flags & SPP_PMTUD_DISABLE)) { 5374 if (stcb) 5375 SCTP_TCB_UNLOCK(stcb); 5376 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5377 return (EINVAL); 5378 } 5379 if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && 5380 ((paddrp->spp_pathmtu < SCTP_SMALLEST_PMTU) || 5381 (paddrp->spp_pathmtu > SCTP_LARGEST_PMTU))) { 5382 if (stcb) 5383 SCTP_TCB_UNLOCK(stcb); 5384 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5385 return (EINVAL); 5386 } 5387 5388 if (stcb != NULL) { 5389 /************************TCB SPECIFIC SET ******************/ 5390 if (net != NULL) { 5391 /************************NET SPECIFIC SET ******************/ 5392 if (paddrp->spp_flags & SPP_HB_DISABLE) { 5393 if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) && 5394 !(net->dest_state & SCTP_ADDR_NOHB)) { 5395 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 5396 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9); 5397 } 5398 net->dest_state |= SCTP_ADDR_NOHB; 5399 } 5400 if (paddrp->spp_flags & SPP_HB_ENABLE) { 5401 if (paddrp->spp_hbinterval) { 5402 net->heart_beat_delay = paddrp->spp_hbinterval; 5403 } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 5404 net->heart_beat_delay = 0; 5405 } 5406 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 5407 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10); 5408 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 5409 net->dest_state &= ~SCTP_ADDR_NOHB; 5410 } 5411 if (paddrp->spp_flags & SPP_HB_DEMAND) { 5412 if (SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) { 5413 sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 5414 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED); 5415 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 5416 } 5417 } 5418 if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { 5419 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 5420 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 5421 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11); 5422 } 5423 net->dest_state |= SCTP_ADDR_NO_PMTUD; 5424 net->mtu = paddrp->spp_pathmtu; 5425 switch (net->ro._l_addr.sa.sa_family) { 5426 #ifdef INET 5427 case AF_INET: 5428 net->mtu += SCTP_MIN_V4_OVERHEAD; 5429 break; 5430 #endif 5431 #ifdef INET6 5432 case AF_INET6: 5433 net->mtu += SCTP_MIN_OVERHEAD; 5434 break; 5435 #endif 5436 default: 5437 break; 5438 } 5439 if (net->mtu < stcb->asoc.smallest_mtu) { 5440 sctp_pathmtu_adjustment(stcb, net->mtu); 5441 } 5442 } 5443 if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 5444 if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 5445 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 5446 } 5447 net->dest_state &= ~SCTP_ADDR_NO_PMTUD; 5448 } 5449 if (paddrp->spp_pathmaxrxt) { 5450 if (net->dest_state & SCTP_ADDR_PF) { 5451 if (net->error_count > paddrp->spp_pathmaxrxt) { 5452 net->dest_state &= ~SCTP_ADDR_PF; 5453 } 5454 } else { 5455 if ((net->error_count <= paddrp->spp_pathmaxrxt) && 5456 (net->error_count > net->pf_threshold)) { 5457 net->dest_state |= SCTP_ADDR_PF; 5458 sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 5459 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, 5460 stcb->sctp_ep, stcb, net, 5461 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_12); 5462 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 5463 } 5464 } 5465 if (net->dest_state & SCTP_ADDR_REACHABLE) { 5466 if (net->error_count > paddrp->spp_pathmaxrxt) { 5467 net->dest_state &= ~SCTP_ADDR_REACHABLE; 5468 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 5469 } 5470 } else { 5471 if (net->error_count <= paddrp->spp_pathmaxrxt) { 5472 net->dest_state |= SCTP_ADDR_REACHABLE; 5473 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 5474 } 5475 } 5476 net->failure_threshold = paddrp->spp_pathmaxrxt; 5477 } 5478 if (paddrp->spp_flags & SPP_DSCP) { 5479 net->dscp = paddrp->spp_dscp & 0xfc; 5480 net->dscp |= 0x01; 5481 } 5482 #ifdef INET6 5483 if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 5484 if (net->ro._l_addr.sa.sa_family == AF_INET6) { 5485 net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 5486 net->flowlabel |= 0x80000000; 5487 } 5488 } 5489 #endif 5490 } else { 5491 /************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/ 5492 if (paddrp->spp_pathmaxrxt != 0) { 5493 stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt; 5494 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5495 if (net->dest_state & SCTP_ADDR_PF) { 5496 if (net->error_count > paddrp->spp_pathmaxrxt) { 5497 net->dest_state &= ~SCTP_ADDR_PF; 5498 } 5499 } else { 5500 if ((net->error_count <= paddrp->spp_pathmaxrxt) && 5501 (net->error_count > net->pf_threshold)) { 5502 net->dest_state |= SCTP_ADDR_PF; 5503 sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 5504 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, 5505 stcb->sctp_ep, stcb, net, 5506 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_13); 5507 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 5508 } 5509 } 5510 if (net->dest_state & SCTP_ADDR_REACHABLE) { 5511 if (net->error_count > paddrp->spp_pathmaxrxt) { 5512 net->dest_state &= ~SCTP_ADDR_REACHABLE; 5513 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 5514 } 5515 } else { 5516 if (net->error_count <= paddrp->spp_pathmaxrxt) { 5517 net->dest_state |= SCTP_ADDR_REACHABLE; 5518 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 5519 } 5520 } 5521 net->failure_threshold = paddrp->spp_pathmaxrxt; 5522 } 5523 } 5524 5525 if (paddrp->spp_flags & SPP_HB_ENABLE) { 5526 if (paddrp->spp_hbinterval != 0) { 5527 stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval; 5528 } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 5529 stcb->asoc.heart_beat_delay = 0; 5530 } 5531 /* Turn back on the timer */ 5532 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5533 if (paddrp->spp_hbinterval != 0) { 5534 net->heart_beat_delay = paddrp->spp_hbinterval; 5535 } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 5536 net->heart_beat_delay = 0; 5537 } 5538 if (net->dest_state & SCTP_ADDR_NOHB) { 5539 net->dest_state &= ~SCTP_ADDR_NOHB; 5540 } 5541 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 5542 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_14); 5543 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 5544 } 5545 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 5546 } 5547 if (paddrp->spp_flags & SPP_HB_DISABLE) { 5548 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5549 if (!(net->dest_state & SCTP_ADDR_NOHB)) { 5550 net->dest_state |= SCTP_ADDR_NOHB; 5551 if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED)) { 5552 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, 5553 inp, stcb, net, 5554 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_15); 5555 } 5556 } 5557 } 5558 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 5559 } 5560 if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { 5561 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5562 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 5563 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 5564 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_16); 5565 } 5566 net->dest_state |= SCTP_ADDR_NO_PMTUD; 5567 net->mtu = paddrp->spp_pathmtu; 5568 switch (net->ro._l_addr.sa.sa_family) { 5569 #ifdef INET 5570 case AF_INET: 5571 net->mtu += SCTP_MIN_V4_OVERHEAD; 5572 break; 5573 #endif 5574 #ifdef INET6 5575 case AF_INET6: 5576 net->mtu += SCTP_MIN_OVERHEAD; 5577 break; 5578 #endif 5579 default: 5580 break; 5581 } 5582 if (net->mtu < stcb->asoc.smallest_mtu) { 5583 sctp_pathmtu_adjustment(stcb, net->mtu); 5584 } 5585 } 5586 stcb->asoc.default_mtu = paddrp->spp_pathmtu; 5587 sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 5588 } 5589 if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 5590 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5591 if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 5592 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 5593 } 5594 net->dest_state &= ~SCTP_ADDR_NO_PMTUD; 5595 } 5596 stcb->asoc.default_mtu = 0; 5597 sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 5598 } 5599 if (paddrp->spp_flags & SPP_DSCP) { 5600 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5601 net->dscp = paddrp->spp_dscp & 0xfc; 5602 net->dscp |= 0x01; 5603 } 5604 stcb->asoc.default_dscp = paddrp->spp_dscp & 0xfc; 5605 stcb->asoc.default_dscp |= 0x01; 5606 } 5607 #ifdef INET6 5608 if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 5609 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5610 if (net->ro._l_addr.sa.sa_family == AF_INET6) { 5611 net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 5612 net->flowlabel |= 0x80000000; 5613 } 5614 } 5615 stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 5616 stcb->asoc.default_flowlabel |= 0x80000000; 5617 } 5618 #endif 5619 } 5620 SCTP_TCB_UNLOCK(stcb); 5621 } else { 5622 /************************NO TCB, SET TO default stuff ******************/ 5623 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5624 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 5625 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5626 (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC))) { 5627 SCTP_INP_WLOCK(inp); 5628 /* 5629 * For the TOS/FLOWLABEL stuff you 5630 * set it with the options on the 5631 * socket 5632 */ 5633 if (paddrp->spp_pathmaxrxt != 0) { 5634 inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt; 5635 } 5636 5637 if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) 5638 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0; 5639 else if (paddrp->spp_hbinterval != 0) { 5640 if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL) 5641 paddrp->spp_hbinterval = SCTP_MAX_HB_INTERVAL; 5642 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval); 5643 } 5644 5645 if (paddrp->spp_flags & SPP_HB_ENABLE) { 5646 if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 5647 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0; 5648 } else if (paddrp->spp_hbinterval) { 5649 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval); 5650 } 5651 sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 5652 } else if (paddrp->spp_flags & SPP_HB_DISABLE) { 5653 sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 5654 } 5655 if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 5656 inp->sctp_ep.default_mtu = 0; 5657 sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 5658 } else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { 5659 inp->sctp_ep.default_mtu = paddrp->spp_pathmtu; 5660 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 5661 } 5662 if (paddrp->spp_flags & SPP_DSCP) { 5663 inp->sctp_ep.default_dscp = paddrp->spp_dscp & 0xfc; 5664 inp->sctp_ep.default_dscp |= 0x01; 5665 } 5666 #ifdef INET6 5667 if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 5668 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 5669 inp->sctp_ep.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 5670 inp->sctp_ep.default_flowlabel |= 0x80000000; 5671 } 5672 } 5673 #endif 5674 SCTP_INP_WUNLOCK(inp); 5675 } else { 5676 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5677 error = EINVAL; 5678 } 5679 } 5680 break; 5681 } 5682 case SCTP_RTOINFO: 5683 { 5684 struct sctp_rtoinfo *srto; 5685 uint32_t new_init, new_min, new_max; 5686 5687 SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, optsize); 5688 SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 5689 5690 if (stcb) { 5691 if (srto->srto_initial) 5692 new_init = srto->srto_initial; 5693 else 5694 new_init = stcb->asoc.initial_rto; 5695 if (srto->srto_max) 5696 new_max = srto->srto_max; 5697 else 5698 new_max = stcb->asoc.maxrto; 5699 if (srto->srto_min) 5700 new_min = srto->srto_min; 5701 else 5702 new_min = stcb->asoc.minrto; 5703 if ((new_min <= new_init) && (new_init <= new_max)) { 5704 stcb->asoc.initial_rto = new_init; 5705 stcb->asoc.maxrto = new_max; 5706 stcb->asoc.minrto = new_min; 5707 } else { 5708 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5709 error = EINVAL; 5710 } 5711 SCTP_TCB_UNLOCK(stcb); 5712 } else { 5713 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5714 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 5715 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5716 (srto->srto_assoc_id == SCTP_FUTURE_ASSOC))) { 5717 SCTP_INP_WLOCK(inp); 5718 if (srto->srto_initial) 5719 new_init = srto->srto_initial; 5720 else 5721 new_init = inp->sctp_ep.initial_rto; 5722 if (srto->srto_max) 5723 new_max = srto->srto_max; 5724 else 5725 new_max = inp->sctp_ep.sctp_maxrto; 5726 if (srto->srto_min) 5727 new_min = srto->srto_min; 5728 else 5729 new_min = inp->sctp_ep.sctp_minrto; 5730 if ((new_min <= new_init) && (new_init <= new_max)) { 5731 inp->sctp_ep.initial_rto = new_init; 5732 inp->sctp_ep.sctp_maxrto = new_max; 5733 inp->sctp_ep.sctp_minrto = new_min; 5734 } else { 5735 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5736 error = EINVAL; 5737 } 5738 SCTP_INP_WUNLOCK(inp); 5739 } else { 5740 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5741 error = EINVAL; 5742 } 5743 } 5744 break; 5745 } 5746 case SCTP_ASSOCINFO: 5747 { 5748 struct sctp_assocparams *sasoc; 5749 5750 SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, optsize); 5751 SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 5752 if (sasoc->sasoc_cookie_life) { 5753 /* boundary check the cookie life */ 5754 if (sasoc->sasoc_cookie_life < 1000) 5755 sasoc->sasoc_cookie_life = 1000; 5756 if (sasoc->sasoc_cookie_life > SCTP_MAX_COOKIE_LIFE) { 5757 sasoc->sasoc_cookie_life = SCTP_MAX_COOKIE_LIFE; 5758 } 5759 } 5760 if (stcb) { 5761 if (sasoc->sasoc_asocmaxrxt) 5762 stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt; 5763 if (sasoc->sasoc_cookie_life) { 5764 stcb->asoc.cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life); 5765 } 5766 SCTP_TCB_UNLOCK(stcb); 5767 } else { 5768 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5769 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 5770 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 5771 (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) { 5772 SCTP_INP_WLOCK(inp); 5773 if (sasoc->sasoc_asocmaxrxt) 5774 inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt; 5775 if (sasoc->sasoc_cookie_life) { 5776 inp->sctp_ep.def_cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life); 5777 } 5778 SCTP_INP_WUNLOCK(inp); 5779 } else { 5780 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5781 error = EINVAL; 5782 } 5783 } 5784 break; 5785 } 5786 case SCTP_INITMSG: 5787 { 5788 struct sctp_initmsg *sinit; 5789 5790 SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, optsize); 5791 SCTP_INP_WLOCK(inp); 5792 if (sinit->sinit_num_ostreams) 5793 inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams; 5794 5795 if (sinit->sinit_max_instreams) 5796 inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams; 5797 5798 if (sinit->sinit_max_attempts) 5799 inp->sctp_ep.max_init_times = sinit->sinit_max_attempts; 5800 5801 if (sinit->sinit_max_init_timeo) 5802 inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo; 5803 SCTP_INP_WUNLOCK(inp); 5804 break; 5805 } 5806 case SCTP_PRIMARY_ADDR: 5807 { 5808 struct sctp_setprim *spa; 5809 struct sctp_nets *net; 5810 struct sockaddr *addr; 5811 #if defined(INET) && defined(INET6) 5812 struct sockaddr_in sin_store; 5813 #endif 5814 5815 SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize); 5816 SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id); 5817 5818 #if defined(INET) && defined(INET6) 5819 if (spa->ssp_addr.ss_family == AF_INET6) { 5820 struct sockaddr_in6 *sin6; 5821 5822 sin6 = (struct sockaddr_in6 *)&spa->ssp_addr; 5823 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 5824 in6_sin6_2_sin(&sin_store, sin6); 5825 addr = (struct sockaddr *)&sin_store; 5826 } else { 5827 addr = (struct sockaddr *)&spa->ssp_addr; 5828 } 5829 } else { 5830 addr = (struct sockaddr *)&spa->ssp_addr; 5831 } 5832 #else 5833 addr = (struct sockaddr *)&spa->ssp_addr; 5834 #endif 5835 if (stcb != NULL) { 5836 net = sctp_findnet(stcb, addr); 5837 } else { 5838 /* 5839 * We increment here since 5840 * sctp_findassociation_ep_addr() wil do a 5841 * decrement if it finds the stcb as long as 5842 * the locked tcb (last argument) is NOT a 5843 * TCB.. aka NULL. 5844 */ 5845 net = NULL; 5846 SCTP_INP_INCR_REF(inp); 5847 stcb = sctp_findassociation_ep_addr(&inp, addr, 5848 &net, NULL, NULL); 5849 if (stcb == NULL) { 5850 SCTP_INP_DECR_REF(inp); 5851 } 5852 } 5853 5854 if ((stcb != NULL) && (net != NULL)) { 5855 if (net != stcb->asoc.primary_destination) { 5856 if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED)) { 5857 /* Ok we need to set it */ 5858 if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) { 5859 if ((stcb->asoc.alternate) && 5860 (!(net->dest_state & SCTP_ADDR_PF)) && 5861 (net->dest_state & SCTP_ADDR_REACHABLE)) { 5862 sctp_free_remote_addr(stcb->asoc.alternate); 5863 stcb->asoc.alternate = NULL; 5864 } 5865 } else { 5866 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5867 error = EINVAL; 5868 } 5869 } else { 5870 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5871 error = EINVAL; 5872 } 5873 } 5874 } else { 5875 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5876 error = EINVAL; 5877 } 5878 if (stcb != NULL) { 5879 SCTP_TCB_UNLOCK(stcb); 5880 } 5881 break; 5882 } 5883 case SCTP_SET_DYNAMIC_PRIMARY: 5884 { 5885 union sctp_sockstore *ss; 5886 5887 error = priv_check(curthread, 5888 PRIV_NETINET_RESERVEDPORT); 5889 if (error) 5890 break; 5891 5892 SCTP_CHECK_AND_CAST(ss, optval, union sctp_sockstore, optsize); 5893 /* SUPER USER CHECK? */ 5894 error = sctp_dynamic_set_primary(&ss->sa, vrf_id); 5895 break; 5896 } 5897 case SCTP_SET_PEER_PRIMARY_ADDR: 5898 { 5899 struct sctp_setpeerprim *sspp; 5900 struct sockaddr *addr; 5901 #if defined(INET) && defined(INET6) 5902 struct sockaddr_in sin_store; 5903 #endif 5904 5905 SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize); 5906 SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id); 5907 if (stcb != NULL) { 5908 struct sctp_ifa *ifa; 5909 5910 #if defined(INET) && defined(INET6) 5911 if (sspp->sspp_addr.ss_family == AF_INET6) { 5912 struct sockaddr_in6 *sin6; 5913 5914 sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr; 5915 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 5916 in6_sin6_2_sin(&sin_store, sin6); 5917 addr = (struct sockaddr *)&sin_store; 5918 } else { 5919 addr = (struct sockaddr *)&sspp->sspp_addr; 5920 } 5921 } else { 5922 addr = (struct sockaddr *)&sspp->sspp_addr; 5923 } 5924 #else 5925 addr = (struct sockaddr *)&sspp->sspp_addr; 5926 #endif 5927 ifa = sctp_find_ifa_by_addr(addr, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED); 5928 if (ifa == NULL) { 5929 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5930 error = EINVAL; 5931 goto out_of_it; 5932 } 5933 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 5934 /* 5935 * Must validate the ifa found is in 5936 * our ep 5937 */ 5938 struct sctp_laddr *laddr; 5939 int found = 0; 5940 5941 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 5942 if (laddr->ifa == NULL) { 5943 SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n", 5944 __func__); 5945 continue; 5946 } 5947 if ((sctp_is_addr_restricted(stcb, laddr->ifa)) && 5948 (!sctp_is_addr_pending(stcb, laddr->ifa))) { 5949 continue; 5950 } 5951 if (laddr->ifa == ifa) { 5952 found = 1; 5953 break; 5954 } 5955 } 5956 if (!found) { 5957 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5958 error = EINVAL; 5959 goto out_of_it; 5960 } 5961 } else { 5962 switch (addr->sa_family) { 5963 #ifdef INET 5964 case AF_INET: 5965 { 5966 struct sockaddr_in *sin; 5967 5968 sin = (struct sockaddr_in *)addr; 5969 if (prison_check_ip4(inp->ip_inp.inp.inp_cred, 5970 &sin->sin_addr) != 0) { 5971 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5972 error = EINVAL; 5973 goto out_of_it; 5974 } 5975 break; 5976 } 5977 #endif 5978 #ifdef INET6 5979 case AF_INET6: 5980 { 5981 struct sockaddr_in6 *sin6; 5982 5983 sin6 = (struct sockaddr_in6 *)addr; 5984 if (prison_check_ip6(inp->ip_inp.inp.inp_cred, 5985 &sin6->sin6_addr) != 0) { 5986 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5987 error = EINVAL; 5988 goto out_of_it; 5989 } 5990 break; 5991 } 5992 #endif 5993 default: 5994 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5995 error = EINVAL; 5996 goto out_of_it; 5997 } 5998 } 5999 if (sctp_set_primary_ip_address_sa(stcb, addr) != 0) { 6000 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6001 error = EINVAL; 6002 } 6003 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED); 6004 out_of_it: 6005 SCTP_TCB_UNLOCK(stcb); 6006 } else { 6007 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6008 error = EINVAL; 6009 } 6010 break; 6011 } 6012 case SCTP_BINDX_ADD_ADDR: 6013 { 6014 struct sctp_getaddresses *addrs; 6015 struct thread *td; 6016 6017 td = (struct thread *)p; 6018 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, 6019 optsize); 6020 #ifdef INET 6021 if (addrs->addr->sa_family == AF_INET) { 6022 if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) { 6023 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6024 error = EINVAL; 6025 break; 6026 } 6027 if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) { 6028 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 6029 break; 6030 } 6031 } else 6032 #endif 6033 #ifdef INET6 6034 if (addrs->addr->sa_family == AF_INET6) { 6035 if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) { 6036 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6037 error = EINVAL; 6038 break; 6039 } 6040 if (td != NULL && (error = prison_local_ip6(td->td_ucred, &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 6041 (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) { 6042 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 6043 break; 6044 } 6045 } else 6046 #endif 6047 { 6048 error = EAFNOSUPPORT; 6049 break; 6050 } 6051 sctp_bindx_add_address(so, inp, addrs->addr, 6052 addrs->sget_assoc_id, vrf_id, 6053 &error, p); 6054 break; 6055 } 6056 case SCTP_BINDX_REM_ADDR: 6057 { 6058 struct sctp_getaddresses *addrs; 6059 struct thread *td; 6060 6061 td = (struct thread *)p; 6062 6063 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize); 6064 #ifdef INET 6065 if (addrs->addr->sa_family == AF_INET) { 6066 if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) { 6067 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6068 error = EINVAL; 6069 break; 6070 } 6071 if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) { 6072 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 6073 break; 6074 } 6075 } else 6076 #endif 6077 #ifdef INET6 6078 if (addrs->addr->sa_family == AF_INET6) { 6079 if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) { 6080 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6081 error = EINVAL; 6082 break; 6083 } 6084 if (td != NULL && 6085 (error = prison_local_ip6(td->td_ucred, 6086 &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 6087 (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) { 6088 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 6089 break; 6090 } 6091 } else 6092 #endif 6093 { 6094 error = EAFNOSUPPORT; 6095 break; 6096 } 6097 sctp_bindx_delete_address(inp, addrs->addr, 6098 addrs->sget_assoc_id, vrf_id, 6099 &error); 6100 break; 6101 } 6102 case SCTP_EVENT: 6103 { 6104 struct sctp_event *event; 6105 uint32_t event_type; 6106 6107 SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, optsize); 6108 SCTP_FIND_STCB(inp, stcb, event->se_assoc_id); 6109 switch (event->se_type) { 6110 case SCTP_ASSOC_CHANGE: 6111 event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT; 6112 break; 6113 case SCTP_PEER_ADDR_CHANGE: 6114 event_type = SCTP_PCB_FLAGS_RECVPADDREVNT; 6115 break; 6116 case SCTP_REMOTE_ERROR: 6117 event_type = SCTP_PCB_FLAGS_RECVPEERERR; 6118 break; 6119 case SCTP_SEND_FAILED: 6120 event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT; 6121 break; 6122 case SCTP_SHUTDOWN_EVENT: 6123 event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT; 6124 break; 6125 case SCTP_ADAPTATION_INDICATION: 6126 event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT; 6127 break; 6128 case SCTP_PARTIAL_DELIVERY_EVENT: 6129 event_type = SCTP_PCB_FLAGS_PDAPIEVNT; 6130 break; 6131 case SCTP_AUTHENTICATION_EVENT: 6132 event_type = SCTP_PCB_FLAGS_AUTHEVNT; 6133 break; 6134 case SCTP_STREAM_RESET_EVENT: 6135 event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT; 6136 break; 6137 case SCTP_SENDER_DRY_EVENT: 6138 event_type = SCTP_PCB_FLAGS_DRYEVNT; 6139 break; 6140 case SCTP_NOTIFICATIONS_STOPPED_EVENT: 6141 event_type = 0; 6142 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 6143 error = ENOTSUP; 6144 break; 6145 case SCTP_ASSOC_RESET_EVENT: 6146 event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT; 6147 break; 6148 case SCTP_STREAM_CHANGE_EVENT: 6149 event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT; 6150 break; 6151 case SCTP_SEND_FAILED_EVENT: 6152 event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT; 6153 break; 6154 default: 6155 event_type = 0; 6156 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6157 error = EINVAL; 6158 break; 6159 } 6160 if (event_type > 0) { 6161 if (stcb) { 6162 if (event->se_on) { 6163 sctp_stcb_feature_on(inp, stcb, event_type); 6164 if (event_type == SCTP_PCB_FLAGS_DRYEVNT) { 6165 if (TAILQ_EMPTY(&stcb->asoc.send_queue) && 6166 TAILQ_EMPTY(&stcb->asoc.sent_queue) && 6167 (stcb->asoc.stream_queue_cnt == 0)) { 6168 sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED); 6169 } 6170 } 6171 } else { 6172 sctp_stcb_feature_off(inp, stcb, event_type); 6173 } 6174 SCTP_TCB_UNLOCK(stcb); 6175 } else { 6176 /* 6177 * We don't want to send up a storm 6178 * of events, so return an error for 6179 * sender dry events 6180 */ 6181 if ((event_type == SCTP_PCB_FLAGS_DRYEVNT) && 6182 (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6183 ((event->se_assoc_id == SCTP_ALL_ASSOC) || 6184 (event->se_assoc_id == SCTP_CURRENT_ASSOC))) { 6185 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 6186 error = ENOTSUP; 6187 break; 6188 } 6189 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6190 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6191 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6192 ((event->se_assoc_id == SCTP_FUTURE_ASSOC) || 6193 (event->se_assoc_id == SCTP_ALL_ASSOC)))) { 6194 SCTP_INP_WLOCK(inp); 6195 if (event->se_on) { 6196 sctp_feature_on(inp, event_type); 6197 } else { 6198 sctp_feature_off(inp, event_type); 6199 } 6200 SCTP_INP_WUNLOCK(inp); 6201 } 6202 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6203 ((event->se_assoc_id == SCTP_CURRENT_ASSOC) || 6204 (event->se_assoc_id == SCTP_ALL_ASSOC))) { 6205 SCTP_INP_RLOCK(inp); 6206 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 6207 SCTP_TCB_LOCK(stcb); 6208 if (event->se_on) { 6209 sctp_stcb_feature_on(inp, stcb, event_type); 6210 } else { 6211 sctp_stcb_feature_off(inp, stcb, event_type); 6212 } 6213 SCTP_TCB_UNLOCK(stcb); 6214 } 6215 SCTP_INP_RUNLOCK(inp); 6216 } 6217 } 6218 } else { 6219 if (stcb) { 6220 SCTP_TCB_UNLOCK(stcb); 6221 } 6222 } 6223 break; 6224 } 6225 case SCTP_RECVRCVINFO: 6226 { 6227 int *onoff; 6228 6229 SCTP_CHECK_AND_CAST(onoff, optval, int, optsize); 6230 SCTP_INP_WLOCK(inp); 6231 if (*onoff != 0) { 6232 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 6233 } else { 6234 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 6235 } 6236 SCTP_INP_WUNLOCK(inp); 6237 break; 6238 } 6239 case SCTP_RECVNXTINFO: 6240 { 6241 int *onoff; 6242 6243 SCTP_CHECK_AND_CAST(onoff, optval, int, optsize); 6244 SCTP_INP_WLOCK(inp); 6245 if (*onoff != 0) { 6246 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 6247 } else { 6248 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 6249 } 6250 SCTP_INP_WUNLOCK(inp); 6251 break; 6252 } 6253 case SCTP_DEFAULT_SNDINFO: 6254 { 6255 struct sctp_sndinfo *info; 6256 uint16_t policy; 6257 6258 SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, optsize); 6259 SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id); 6260 6261 if (stcb) { 6262 if (info->snd_sid < stcb->asoc.streamoutcnt) { 6263 stcb->asoc.def_send.sinfo_stream = info->snd_sid; 6264 policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 6265 stcb->asoc.def_send.sinfo_flags = info->snd_flags; 6266 stcb->asoc.def_send.sinfo_flags |= policy; 6267 stcb->asoc.def_send.sinfo_ppid = info->snd_ppid; 6268 stcb->asoc.def_send.sinfo_context = info->snd_context; 6269 } else { 6270 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6271 error = EINVAL; 6272 } 6273 SCTP_TCB_UNLOCK(stcb); 6274 } else { 6275 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6276 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6277 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6278 ((info->snd_assoc_id == SCTP_FUTURE_ASSOC) || 6279 (info->snd_assoc_id == SCTP_ALL_ASSOC)))) { 6280 SCTP_INP_WLOCK(inp); 6281 inp->def_send.sinfo_stream = info->snd_sid; 6282 policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags); 6283 inp->def_send.sinfo_flags = info->snd_flags; 6284 inp->def_send.sinfo_flags |= policy; 6285 inp->def_send.sinfo_ppid = info->snd_ppid; 6286 inp->def_send.sinfo_context = info->snd_context; 6287 SCTP_INP_WUNLOCK(inp); 6288 } 6289 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6290 ((info->snd_assoc_id == SCTP_CURRENT_ASSOC) || 6291 (info->snd_assoc_id == SCTP_ALL_ASSOC))) { 6292 SCTP_INP_RLOCK(inp); 6293 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 6294 SCTP_TCB_LOCK(stcb); 6295 if (info->snd_sid < stcb->asoc.streamoutcnt) { 6296 stcb->asoc.def_send.sinfo_stream = info->snd_sid; 6297 policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 6298 stcb->asoc.def_send.sinfo_flags = info->snd_flags; 6299 stcb->asoc.def_send.sinfo_flags |= policy; 6300 stcb->asoc.def_send.sinfo_ppid = info->snd_ppid; 6301 stcb->asoc.def_send.sinfo_context = info->snd_context; 6302 } 6303 SCTP_TCB_UNLOCK(stcb); 6304 } 6305 SCTP_INP_RUNLOCK(inp); 6306 } 6307 } 6308 break; 6309 } 6310 case SCTP_DEFAULT_PRINFO: 6311 { 6312 struct sctp_default_prinfo *info; 6313 6314 SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize); 6315 SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id); 6316 6317 if (info->pr_policy > SCTP_PR_SCTP_MAX) { 6318 if (stcb) { 6319 SCTP_TCB_UNLOCK(stcb); 6320 } 6321 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6322 error = EINVAL; 6323 break; 6324 } 6325 if (stcb) { 6326 stcb->asoc.def_send.sinfo_flags &= 0xfff0; 6327 stcb->asoc.def_send.sinfo_flags |= info->pr_policy; 6328 stcb->asoc.def_send.sinfo_timetolive = info->pr_value; 6329 SCTP_TCB_UNLOCK(stcb); 6330 } else { 6331 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6332 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6333 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6334 ((info->pr_assoc_id == SCTP_FUTURE_ASSOC) || 6335 (info->pr_assoc_id == SCTP_ALL_ASSOC)))) { 6336 SCTP_INP_WLOCK(inp); 6337 inp->def_send.sinfo_flags &= 0xfff0; 6338 inp->def_send.sinfo_flags |= info->pr_policy; 6339 inp->def_send.sinfo_timetolive = info->pr_value; 6340 SCTP_INP_WUNLOCK(inp); 6341 } 6342 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6343 ((info->pr_assoc_id == SCTP_CURRENT_ASSOC) || 6344 (info->pr_assoc_id == SCTP_ALL_ASSOC))) { 6345 SCTP_INP_RLOCK(inp); 6346 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 6347 SCTP_TCB_LOCK(stcb); 6348 stcb->asoc.def_send.sinfo_flags &= 0xfff0; 6349 stcb->asoc.def_send.sinfo_flags |= info->pr_policy; 6350 stcb->asoc.def_send.sinfo_timetolive = info->pr_value; 6351 SCTP_TCB_UNLOCK(stcb); 6352 } 6353 SCTP_INP_RUNLOCK(inp); 6354 } 6355 } 6356 break; 6357 } 6358 case SCTP_PEER_ADDR_THLDS: 6359 /* Applies to the specific association */ 6360 { 6361 struct sctp_paddrthlds *thlds; 6362 struct sctp_nets *net; 6363 struct sockaddr *addr; 6364 #if defined(INET) && defined(INET6) 6365 struct sockaddr_in sin_store; 6366 #endif 6367 6368 SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize); 6369 SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); 6370 6371 #if defined(INET) && defined(INET6) 6372 if (thlds->spt_address.ss_family == AF_INET6) { 6373 struct sockaddr_in6 *sin6; 6374 6375 sin6 = (struct sockaddr_in6 *)&thlds->spt_address; 6376 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 6377 in6_sin6_2_sin(&sin_store, sin6); 6378 addr = (struct sockaddr *)&sin_store; 6379 } else { 6380 addr = (struct sockaddr *)&thlds->spt_address; 6381 } 6382 } else { 6383 addr = (struct sockaddr *)&thlds->spt_address; 6384 } 6385 #else 6386 addr = (struct sockaddr *)&thlds->spt_address; 6387 #endif 6388 if (stcb != NULL) { 6389 net = sctp_findnet(stcb, addr); 6390 } else { 6391 /* 6392 * We increment here since 6393 * sctp_findassociation_ep_addr() wil do a 6394 * decrement if it finds the stcb as long as 6395 * the locked tcb (last argument) is NOT a 6396 * TCB.. aka NULL. 6397 */ 6398 net = NULL; 6399 SCTP_INP_INCR_REF(inp); 6400 stcb = sctp_findassociation_ep_addr(&inp, addr, 6401 &net, NULL, NULL); 6402 if (stcb == NULL) { 6403 SCTP_INP_DECR_REF(inp); 6404 } 6405 } 6406 if ((stcb != NULL) && (net == NULL)) { 6407 #ifdef INET 6408 if (addr->sa_family == AF_INET) { 6409 6410 struct sockaddr_in *sin; 6411 6412 sin = (struct sockaddr_in *)addr; 6413 if (sin->sin_addr.s_addr != INADDR_ANY) { 6414 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6415 SCTP_TCB_UNLOCK(stcb); 6416 error = EINVAL; 6417 break; 6418 } 6419 } else 6420 #endif 6421 #ifdef INET6 6422 if (addr->sa_family == AF_INET6) { 6423 struct sockaddr_in6 *sin6; 6424 6425 sin6 = (struct sockaddr_in6 *)addr; 6426 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 6427 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6428 SCTP_TCB_UNLOCK(stcb); 6429 error = EINVAL; 6430 break; 6431 } 6432 } else 6433 #endif 6434 { 6435 error = EAFNOSUPPORT; 6436 SCTP_TCB_UNLOCK(stcb); 6437 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 6438 break; 6439 } 6440 } 6441 if (thlds->spt_pathcpthld != 0xffff) { 6442 if (stcb != NULL) { 6443 SCTP_TCB_UNLOCK(stcb); 6444 } 6445 error = EINVAL; 6446 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 6447 break; 6448 } 6449 if (stcb != NULL) { 6450 if (net != NULL) { 6451 net->failure_threshold = thlds->spt_pathmaxrxt; 6452 net->pf_threshold = thlds->spt_pathpfthld; 6453 if (net->dest_state & SCTP_ADDR_PF) { 6454 if ((net->error_count > net->failure_threshold) || 6455 (net->error_count <= net->pf_threshold)) { 6456 net->dest_state &= ~SCTP_ADDR_PF; 6457 } 6458 } else { 6459 if ((net->error_count > net->pf_threshold) && 6460 (net->error_count <= net->failure_threshold)) { 6461 net->dest_state |= SCTP_ADDR_PF; 6462 sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 6463 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, 6464 stcb->sctp_ep, stcb, net, 6465 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_17); 6466 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 6467 } 6468 } 6469 if (net->dest_state & SCTP_ADDR_REACHABLE) { 6470 if (net->error_count > net->failure_threshold) { 6471 net->dest_state &= ~SCTP_ADDR_REACHABLE; 6472 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 6473 } 6474 } else { 6475 if (net->error_count <= net->failure_threshold) { 6476 net->dest_state |= SCTP_ADDR_REACHABLE; 6477 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 6478 } 6479 } 6480 } else { 6481 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 6482 net->failure_threshold = thlds->spt_pathmaxrxt; 6483 net->pf_threshold = thlds->spt_pathpfthld; 6484 if (net->dest_state & SCTP_ADDR_PF) { 6485 if ((net->error_count > net->failure_threshold) || 6486 (net->error_count <= net->pf_threshold)) { 6487 net->dest_state &= ~SCTP_ADDR_PF; 6488 } 6489 } else { 6490 if ((net->error_count > net->pf_threshold) && 6491 (net->error_count <= net->failure_threshold)) { 6492 net->dest_state |= SCTP_ADDR_PF; 6493 sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 6494 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, 6495 stcb->sctp_ep, stcb, net, 6496 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_18); 6497 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 6498 } 6499 } 6500 if (net->dest_state & SCTP_ADDR_REACHABLE) { 6501 if (net->error_count > net->failure_threshold) { 6502 net->dest_state &= ~SCTP_ADDR_REACHABLE; 6503 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 6504 } 6505 } else { 6506 if (net->error_count <= net->failure_threshold) { 6507 net->dest_state |= SCTP_ADDR_REACHABLE; 6508 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 6509 } 6510 } 6511 } 6512 stcb->asoc.def_net_failure = thlds->spt_pathmaxrxt; 6513 stcb->asoc.def_net_pf_threshold = thlds->spt_pathpfthld; 6514 } 6515 SCTP_TCB_UNLOCK(stcb); 6516 } else { 6517 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6518 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6519 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6520 (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC))) { 6521 SCTP_INP_WLOCK(inp); 6522 inp->sctp_ep.def_net_failure = thlds->spt_pathmaxrxt; 6523 inp->sctp_ep.def_net_pf_threshold = thlds->spt_pathpfthld; 6524 SCTP_INP_WUNLOCK(inp); 6525 } else { 6526 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6527 error = EINVAL; 6528 } 6529 } 6530 break; 6531 } 6532 case SCTP_REMOTE_UDP_ENCAPS_PORT: 6533 { 6534 struct sctp_udpencaps *encaps; 6535 struct sctp_nets *net; 6536 struct sockaddr *addr; 6537 #if defined(INET) && defined(INET6) 6538 struct sockaddr_in sin_store; 6539 #endif 6540 6541 SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize); 6542 SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); 6543 6544 #if defined(INET) && defined(INET6) 6545 if (encaps->sue_address.ss_family == AF_INET6) { 6546 struct sockaddr_in6 *sin6; 6547 6548 sin6 = (struct sockaddr_in6 *)&encaps->sue_address; 6549 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 6550 in6_sin6_2_sin(&sin_store, sin6); 6551 addr = (struct sockaddr *)&sin_store; 6552 } else { 6553 addr = (struct sockaddr *)&encaps->sue_address; 6554 } 6555 } else { 6556 addr = (struct sockaddr *)&encaps->sue_address; 6557 } 6558 #else 6559 addr = (struct sockaddr *)&encaps->sue_address; 6560 #endif 6561 if (stcb != NULL) { 6562 net = sctp_findnet(stcb, addr); 6563 } else { 6564 /* 6565 * We increment here since 6566 * sctp_findassociation_ep_addr() wil do a 6567 * decrement if it finds the stcb as long as 6568 * the locked tcb (last argument) is NOT a 6569 * TCB.. aka NULL. 6570 */ 6571 net = NULL; 6572 SCTP_INP_INCR_REF(inp); 6573 stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL); 6574 if (stcb == NULL) { 6575 SCTP_INP_DECR_REF(inp); 6576 } 6577 } 6578 if ((stcb != NULL) && (net == NULL)) { 6579 #ifdef INET 6580 if (addr->sa_family == AF_INET) { 6581 6582 struct sockaddr_in *sin; 6583 6584 sin = (struct sockaddr_in *)addr; 6585 if (sin->sin_addr.s_addr != INADDR_ANY) { 6586 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6587 SCTP_TCB_UNLOCK(stcb); 6588 error = EINVAL; 6589 break; 6590 } 6591 } else 6592 #endif 6593 #ifdef INET6 6594 if (addr->sa_family == AF_INET6) { 6595 struct sockaddr_in6 *sin6; 6596 6597 sin6 = (struct sockaddr_in6 *)addr; 6598 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 6599 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6600 SCTP_TCB_UNLOCK(stcb); 6601 error = EINVAL; 6602 break; 6603 } 6604 } else 6605 #endif 6606 { 6607 error = EAFNOSUPPORT; 6608 SCTP_TCB_UNLOCK(stcb); 6609 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 6610 break; 6611 } 6612 } 6613 6614 if (stcb != NULL) { 6615 if (net != NULL) { 6616 net->port = encaps->sue_port; 6617 } else { 6618 stcb->asoc.port = encaps->sue_port; 6619 } 6620 SCTP_TCB_UNLOCK(stcb); 6621 } else { 6622 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6623 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6624 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6625 (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC))) { 6626 SCTP_INP_WLOCK(inp); 6627 inp->sctp_ep.port = encaps->sue_port; 6628 SCTP_INP_WUNLOCK(inp); 6629 } else { 6630 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6631 error = EINVAL; 6632 } 6633 } 6634 break; 6635 } 6636 case SCTP_ECN_SUPPORTED: 6637 { 6638 struct sctp_assoc_value *av; 6639 6640 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6641 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6642 6643 if (stcb) { 6644 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6645 error = EINVAL; 6646 SCTP_TCB_UNLOCK(stcb); 6647 } else { 6648 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6649 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6650 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6651 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6652 SCTP_INP_WLOCK(inp); 6653 if (av->assoc_value == 0) { 6654 inp->ecn_supported = 0; 6655 } else { 6656 inp->ecn_supported = 1; 6657 } 6658 SCTP_INP_WUNLOCK(inp); 6659 } else { 6660 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6661 error = EINVAL; 6662 } 6663 } 6664 break; 6665 } 6666 case SCTP_PR_SUPPORTED: 6667 { 6668 struct sctp_assoc_value *av; 6669 6670 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6671 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6672 6673 if (stcb) { 6674 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6675 error = EINVAL; 6676 SCTP_TCB_UNLOCK(stcb); 6677 } else { 6678 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6679 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6680 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6681 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6682 SCTP_INP_WLOCK(inp); 6683 if (av->assoc_value == 0) { 6684 inp->prsctp_supported = 0; 6685 } else { 6686 inp->prsctp_supported = 1; 6687 } 6688 SCTP_INP_WUNLOCK(inp); 6689 } else { 6690 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6691 error = EINVAL; 6692 } 6693 } 6694 break; 6695 } 6696 case SCTP_AUTH_SUPPORTED: 6697 { 6698 struct sctp_assoc_value *av; 6699 6700 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6701 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6702 6703 if (stcb) { 6704 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6705 error = EINVAL; 6706 SCTP_TCB_UNLOCK(stcb); 6707 } else { 6708 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6709 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6710 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6711 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6712 if ((av->assoc_value == 0) && 6713 (inp->asconf_supported == 1)) { 6714 /* 6715 * AUTH is required for 6716 * ASCONF 6717 */ 6718 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6719 error = EINVAL; 6720 } else { 6721 SCTP_INP_WLOCK(inp); 6722 if (av->assoc_value == 0) { 6723 inp->auth_supported = 0; 6724 } else { 6725 inp->auth_supported = 1; 6726 } 6727 SCTP_INP_WUNLOCK(inp); 6728 } 6729 } else { 6730 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6731 error = EINVAL; 6732 } 6733 } 6734 break; 6735 } 6736 case SCTP_ASCONF_SUPPORTED: 6737 { 6738 struct sctp_assoc_value *av; 6739 6740 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6741 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6742 6743 if (stcb) { 6744 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6745 error = EINVAL; 6746 SCTP_TCB_UNLOCK(stcb); 6747 } else { 6748 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6749 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6750 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6751 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6752 if ((av->assoc_value != 0) && 6753 (inp->auth_supported == 0)) { 6754 /* 6755 * AUTH is required for 6756 * ASCONF 6757 */ 6758 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6759 error = EINVAL; 6760 } else { 6761 SCTP_INP_WLOCK(inp); 6762 if (av->assoc_value == 0) { 6763 inp->asconf_supported = 0; 6764 sctp_auth_delete_chunk(SCTP_ASCONF, 6765 inp->sctp_ep.local_auth_chunks); 6766 sctp_auth_delete_chunk(SCTP_ASCONF_ACK, 6767 inp->sctp_ep.local_auth_chunks); 6768 } else { 6769 inp->asconf_supported = 1; 6770 sctp_auth_add_chunk(SCTP_ASCONF, 6771 inp->sctp_ep.local_auth_chunks); 6772 sctp_auth_add_chunk(SCTP_ASCONF_ACK, 6773 inp->sctp_ep.local_auth_chunks); 6774 } 6775 SCTP_INP_WUNLOCK(inp); 6776 } 6777 } else { 6778 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6779 error = EINVAL; 6780 } 6781 } 6782 break; 6783 } 6784 case SCTP_RECONFIG_SUPPORTED: 6785 { 6786 struct sctp_assoc_value *av; 6787 6788 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6789 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6790 6791 if (stcb) { 6792 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6793 error = EINVAL; 6794 SCTP_TCB_UNLOCK(stcb); 6795 } else { 6796 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6797 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6798 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6799 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6800 SCTP_INP_WLOCK(inp); 6801 if (av->assoc_value == 0) { 6802 inp->reconfig_supported = 0; 6803 } else { 6804 inp->reconfig_supported = 1; 6805 } 6806 SCTP_INP_WUNLOCK(inp); 6807 } else { 6808 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6809 error = EINVAL; 6810 } 6811 } 6812 break; 6813 } 6814 case SCTP_NRSACK_SUPPORTED: 6815 { 6816 struct sctp_assoc_value *av; 6817 6818 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6819 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6820 6821 if (stcb) { 6822 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6823 error = EINVAL; 6824 SCTP_TCB_UNLOCK(stcb); 6825 } else { 6826 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6827 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6828 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6829 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6830 SCTP_INP_WLOCK(inp); 6831 if (av->assoc_value == 0) { 6832 inp->nrsack_supported = 0; 6833 } else { 6834 inp->nrsack_supported = 1; 6835 } 6836 SCTP_INP_WUNLOCK(inp); 6837 } else { 6838 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6839 error = EINVAL; 6840 } 6841 } 6842 break; 6843 } 6844 case SCTP_PKTDROP_SUPPORTED: 6845 { 6846 struct sctp_assoc_value *av; 6847 6848 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6849 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6850 6851 if (stcb) { 6852 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6853 error = EINVAL; 6854 SCTP_TCB_UNLOCK(stcb); 6855 } else { 6856 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6857 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6858 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6859 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6860 SCTP_INP_WLOCK(inp); 6861 if (av->assoc_value == 0) { 6862 inp->pktdrop_supported = 0; 6863 } else { 6864 inp->pktdrop_supported = 1; 6865 } 6866 SCTP_INP_WUNLOCK(inp); 6867 } else { 6868 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6869 error = EINVAL; 6870 } 6871 } 6872 break; 6873 } 6874 case SCTP_MAX_CWND: 6875 { 6876 struct sctp_assoc_value *av; 6877 struct sctp_nets *net; 6878 6879 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 6880 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 6881 6882 if (stcb) { 6883 stcb->asoc.max_cwnd = av->assoc_value; 6884 if (stcb->asoc.max_cwnd > 0) { 6885 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 6886 if ((net->cwnd > stcb->asoc.max_cwnd) && 6887 (net->cwnd > (net->mtu - sizeof(struct sctphdr)))) { 6888 net->cwnd = stcb->asoc.max_cwnd; 6889 if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) { 6890 net->cwnd = net->mtu - sizeof(struct sctphdr); 6891 } 6892 } 6893 } 6894 } 6895 SCTP_TCB_UNLOCK(stcb); 6896 } else { 6897 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6898 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6899 ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) && 6900 (av->assoc_id == SCTP_FUTURE_ASSOC))) { 6901 SCTP_INP_WLOCK(inp); 6902 inp->max_cwnd = av->assoc_value; 6903 SCTP_INP_WUNLOCK(inp); 6904 } else { 6905 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6906 error = EINVAL; 6907 } 6908 } 6909 break; 6910 } 6911 default: 6912 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 6913 error = ENOPROTOOPT; 6914 break; 6915 } /* end switch (opt) */ 6916 return (error); 6917 } 6918 6919 int 6920 sctp_ctloutput(struct socket *so, struct sockopt *sopt) 6921 { 6922 struct epoch_tracker et; 6923 struct sctp_inpcb *inp; 6924 void *optval = NULL; 6925 void *p; 6926 size_t optsize = 0; 6927 int error = 0; 6928 6929 if ((sopt->sopt_level == SOL_SOCKET) && 6930 (sopt->sopt_name == SO_SETFIB)) { 6931 inp = (struct sctp_inpcb *)so->so_pcb; 6932 if (inp == NULL) { 6933 SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS); 6934 return (EINVAL); 6935 } 6936 SCTP_INP_WLOCK(inp); 6937 inp->fibnum = so->so_fibnum; 6938 SCTP_INP_WUNLOCK(inp); 6939 return (0); 6940 } 6941 if (sopt->sopt_level != IPPROTO_SCTP) { 6942 /* wrong proto level... send back up to IP */ 6943 #ifdef INET6 6944 if (INP_CHECK_SOCKAF(so, AF_INET6)) 6945 error = ip6_ctloutput(so, sopt); 6946 #endif /* INET6 */ 6947 #if defined(INET) && defined(INET6) 6948 else 6949 #endif 6950 #ifdef INET 6951 error = ip_ctloutput(so, sopt); 6952 #endif 6953 return (error); 6954 } 6955 optsize = sopt->sopt_valsize; 6956 if (optsize > SCTP_SOCKET_OPTION_LIMIT) { 6957 SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS); 6958 return (ENOBUFS); 6959 } 6960 if (optsize) { 6961 SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT); 6962 if (optval == NULL) { 6963 SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS); 6964 return (ENOBUFS); 6965 } 6966 error = sooptcopyin(sopt, optval, optsize, optsize); 6967 if (error) { 6968 SCTP_FREE(optval, SCTP_M_SOCKOPT); 6969 goto out; 6970 } 6971 } 6972 p = (void *)sopt->sopt_td; 6973 if (sopt->sopt_dir == SOPT_SET) { 6974 NET_EPOCH_ENTER(et); 6975 error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p); 6976 NET_EPOCH_EXIT(et); 6977 } else if (sopt->sopt_dir == SOPT_GET) { 6978 error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p); 6979 } else { 6980 SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6981 error = EINVAL; 6982 } 6983 if ((error == 0) && (optval != NULL)) { 6984 error = sooptcopyout(sopt, optval, optsize); 6985 SCTP_FREE(optval, SCTP_M_SOCKOPT); 6986 } else if (optval != NULL) { 6987 SCTP_FREE(optval, SCTP_M_SOCKOPT); 6988 } 6989 out: 6990 return (error); 6991 } 6992 6993 #ifdef INET 6994 static int 6995 sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) 6996 { 6997 struct epoch_tracker et; 6998 int error = 0; 6999 int create_lock_on = 0; 7000 uint32_t vrf_id; 7001 struct sctp_inpcb *inp; 7002 struct sctp_tcb *stcb = NULL; 7003 7004 inp = (struct sctp_inpcb *)so->so_pcb; 7005 if (inp == NULL) { 7006 /* I made the same as TCP since we are not setup? */ 7007 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7008 return (ECONNRESET); 7009 } 7010 if (addr == NULL) { 7011 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7012 return EINVAL; 7013 } 7014 7015 switch (addr->sa_family) { 7016 #ifdef INET6 7017 case AF_INET6: 7018 { 7019 struct sockaddr_in6 *sin6; 7020 7021 if (addr->sa_len != sizeof(struct sockaddr_in6)) { 7022 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7023 return (EINVAL); 7024 } 7025 sin6 = (struct sockaddr_in6 *)addr; 7026 if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6->sin6_addr)) != 0) { 7027 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 7028 return (error); 7029 } 7030 break; 7031 } 7032 #endif 7033 #ifdef INET 7034 case AF_INET: 7035 { 7036 struct sockaddr_in *sin; 7037 7038 if (addr->sa_len != sizeof(struct sockaddr_in)) { 7039 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7040 return (EINVAL); 7041 } 7042 sin = (struct sockaddr_in *)addr; 7043 if (p != NULL && (error = prison_remote_ip4(p->td_ucred, &sin->sin_addr)) != 0) { 7044 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 7045 return (error); 7046 } 7047 break; 7048 } 7049 #endif 7050 default: 7051 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 7052 return (EAFNOSUPPORT); 7053 } 7054 SCTP_INP_INCR_REF(inp); 7055 SCTP_ASOC_CREATE_LOCK(inp); 7056 create_lock_on = 1; 7057 NET_EPOCH_ENTER(et); 7058 7059 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 7060 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 7061 /* Should I really unlock ? */ 7062 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 7063 error = EFAULT; 7064 goto out_now; 7065 } 7066 #ifdef INET6 7067 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 7068 (addr->sa_family == AF_INET6)) { 7069 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7070 error = EINVAL; 7071 goto out_now; 7072 } 7073 #endif 7074 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 7075 SCTP_PCB_FLAGS_UNBOUND) { 7076 /* Bind a ephemeral port */ 7077 error = sctp_inpcb_bind(so, NULL, NULL, p); 7078 if (error) { 7079 goto out_now; 7080 } 7081 } 7082 /* Now do we connect? */ 7083 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 7084 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 7085 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7086 error = EINVAL; 7087 goto out_now; 7088 } 7089 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 7090 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 7091 /* We are already connected AND the TCP model */ 7092 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 7093 error = EADDRINUSE; 7094 goto out_now; 7095 } 7096 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 7097 SCTP_INP_RLOCK(inp); 7098 stcb = LIST_FIRST(&inp->sctp_asoc_list); 7099 SCTP_INP_RUNLOCK(inp); 7100 } else { 7101 /* 7102 * We increment here since sctp_findassociation_ep_addr() 7103 * will do a decrement if it finds the stcb as long as the 7104 * locked tcb (last argument) is NOT a TCB.. aka NULL. 7105 */ 7106 SCTP_INP_INCR_REF(inp); 7107 stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 7108 if (stcb == NULL) { 7109 SCTP_INP_DECR_REF(inp); 7110 } else { 7111 SCTP_TCB_UNLOCK(stcb); 7112 } 7113 } 7114 if (stcb != NULL) { 7115 /* Already have or am bring up an association */ 7116 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 7117 error = EALREADY; 7118 goto out_now; 7119 } 7120 7121 vrf_id = inp->def_vrf_id; 7122 /* We are GOOD to go */ 7123 stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, 7124 inp->sctp_ep.pre_open_stream_count, 7125 inp->sctp_ep.port, p, 7126 SCTP_INITIALIZE_AUTH_PARAMS); 7127 if (stcb == NULL) { 7128 /* Gak! no memory */ 7129 goto out_now; 7130 } 7131 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 7132 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 7133 /* Set the connected flag so we can queue data */ 7134 soisconnecting(so); 7135 } 7136 SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT); 7137 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 7138 7139 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 7140 SCTP_TCB_UNLOCK(stcb); 7141 out_now: 7142 NET_EPOCH_EXIT(et); 7143 if (create_lock_on) { 7144 SCTP_ASOC_CREATE_UNLOCK(inp); 7145 } 7146 SCTP_INP_DECR_REF(inp); 7147 return (error); 7148 } 7149 #endif 7150 7151 int 7152 sctp_listen(struct socket *so, int backlog, struct thread *p) 7153 { 7154 /* 7155 * Note this module depends on the protocol processing being called 7156 * AFTER any socket level flags and backlog are applied to the 7157 * socket. The traditional way that the socket flags are applied is 7158 * AFTER protocol processing. We have made a change to the 7159 * sys/kern/uipc_socket.c module to reverse this but this MUST be in 7160 * place if the socket API for SCTP is to work properly. 7161 */ 7162 7163 int error = 0; 7164 struct sctp_inpcb *inp; 7165 7166 inp = (struct sctp_inpcb *)so->so_pcb; 7167 if (inp == NULL) { 7168 /* I made the same as TCP since we are not setup? */ 7169 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7170 return (ECONNRESET); 7171 } 7172 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) { 7173 /* See if we have a listener */ 7174 struct sctp_inpcb *tinp; 7175 union sctp_sockstore store; 7176 7177 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 7178 /* not bound all */ 7179 struct sctp_laddr *laddr; 7180 7181 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 7182 memcpy(&store, &laddr->ifa->address, sizeof(store)); 7183 switch (store.sa.sa_family) { 7184 #ifdef INET 7185 case AF_INET: 7186 store.sin.sin_port = inp->sctp_lport; 7187 break; 7188 #endif 7189 #ifdef INET6 7190 case AF_INET6: 7191 store.sin6.sin6_port = inp->sctp_lport; 7192 break; 7193 #endif 7194 default: 7195 break; 7196 } 7197 tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); 7198 if (tinp && (tinp != inp) && 7199 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 7200 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 7201 (SCTP_IS_LISTENING(tinp))) { 7202 /* 7203 * we have a listener already and 7204 * its not this inp. 7205 */ 7206 SCTP_INP_DECR_REF(tinp); 7207 return (EADDRINUSE); 7208 } else if (tinp) { 7209 SCTP_INP_DECR_REF(tinp); 7210 } 7211 } 7212 } else { 7213 /* Setup a local addr bound all */ 7214 memset(&store, 0, sizeof(store)); 7215 #ifdef INET6 7216 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 7217 store.sa.sa_family = AF_INET6; 7218 store.sa.sa_len = sizeof(struct sockaddr_in6); 7219 } 7220 #endif 7221 #ifdef INET 7222 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 7223 store.sa.sa_family = AF_INET; 7224 store.sa.sa_len = sizeof(struct sockaddr_in); 7225 } 7226 #endif 7227 switch (store.sa.sa_family) { 7228 #ifdef INET 7229 case AF_INET: 7230 store.sin.sin_port = inp->sctp_lport; 7231 break; 7232 #endif 7233 #ifdef INET6 7234 case AF_INET6: 7235 store.sin6.sin6_port = inp->sctp_lport; 7236 break; 7237 #endif 7238 default: 7239 break; 7240 } 7241 tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); 7242 if (tinp && (tinp != inp) && 7243 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 7244 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 7245 (SCTP_IS_LISTENING(tinp))) { 7246 /* 7247 * we have a listener already and its not 7248 * this inp. 7249 */ 7250 SCTP_INP_DECR_REF(tinp); 7251 return (EADDRINUSE); 7252 } else if (tinp) { 7253 SCTP_INP_DECR_REF(tinp); 7254 } 7255 } 7256 } 7257 SCTP_INP_RLOCK(inp); 7258 #ifdef SCTP_LOCK_LOGGING 7259 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) { 7260 sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK); 7261 } 7262 #endif 7263 SOCK_LOCK(so); 7264 error = solisten_proto_check(so); 7265 SOCK_UNLOCK(so); 7266 if (error) { 7267 SCTP_INP_RUNLOCK(inp); 7268 return (error); 7269 } 7270 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) && 7271 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 7272 /* 7273 * The unlucky case - We are in the tcp pool with this guy. 7274 * - Someone else is in the main inp slot. - We must move 7275 * this guy (the listener) to the main slot - We must then 7276 * move the guy that was listener to the TCP Pool. 7277 */ 7278 if (sctp_swap_inpcb_for_listen(inp)) { 7279 SCTP_INP_RUNLOCK(inp); 7280 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 7281 return (EADDRINUSE); 7282 } 7283 } 7284 7285 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 7286 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 7287 /* We are already connected AND the TCP model */ 7288 SCTP_INP_RUNLOCK(inp); 7289 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 7290 return (EADDRINUSE); 7291 } 7292 SCTP_INP_RUNLOCK(inp); 7293 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 7294 /* We must do a bind. */ 7295 if ((error = sctp_inpcb_bind(so, NULL, NULL, p))) { 7296 /* bind error, probably perm */ 7297 return (error); 7298 } 7299 } 7300 SCTP_INP_WLOCK(inp); 7301 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) == 0) { 7302 SOCK_LOCK(so); 7303 solisten_proto(so, backlog); 7304 SOCK_UNLOCK(so); 7305 } 7306 if (backlog > 0) { 7307 inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING; 7308 } else { 7309 inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING; 7310 } 7311 SCTP_INP_WUNLOCK(inp); 7312 return (error); 7313 } 7314 7315 static int sctp_defered_wakeup_cnt = 0; 7316 7317 int 7318 sctp_accept(struct socket *so, struct sockaddr **addr) 7319 { 7320 struct sctp_tcb *stcb; 7321 struct sctp_inpcb *inp; 7322 union sctp_sockstore store; 7323 #ifdef INET6 7324 int error; 7325 #endif 7326 inp = (struct sctp_inpcb *)so->so_pcb; 7327 7328 if (inp == NULL) { 7329 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7330 return (ECONNRESET); 7331 } 7332 SCTP_INP_WLOCK(inp); 7333 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 7334 SCTP_INP_WUNLOCK(inp); 7335 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 7336 return (EOPNOTSUPP); 7337 } 7338 if (so->so_state & SS_ISDISCONNECTED) { 7339 SCTP_INP_WUNLOCK(inp); 7340 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ECONNABORTED); 7341 return (ECONNABORTED); 7342 } 7343 stcb = LIST_FIRST(&inp->sctp_asoc_list); 7344 if (stcb == NULL) { 7345 SCTP_INP_WUNLOCK(inp); 7346 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7347 return (ECONNRESET); 7348 } 7349 SCTP_TCB_LOCK(stcb); 7350 store = stcb->asoc.primary_destination->ro._l_addr; 7351 SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE); 7352 /* Wake any delayed sleep action */ 7353 if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { 7354 inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE; 7355 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) { 7356 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; 7357 SOCKBUF_LOCK(&inp->sctp_socket->so_snd); 7358 if (sowriteable(inp->sctp_socket)) { 7359 sowwakeup_locked(inp->sctp_socket); 7360 } else { 7361 SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd); 7362 } 7363 } 7364 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) { 7365 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; 7366 SOCKBUF_LOCK(&inp->sctp_socket->so_rcv); 7367 if (soreadable(inp->sctp_socket)) { 7368 sctp_defered_wakeup_cnt++; 7369 sorwakeup_locked(inp->sctp_socket); 7370 } else { 7371 SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv); 7372 } 7373 } 7374 } 7375 SCTP_INP_WUNLOCK(inp); 7376 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 7377 sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 7378 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_19); 7379 } else { 7380 SCTP_TCB_UNLOCK(stcb); 7381 } 7382 switch (store.sa.sa_family) { 7383 #ifdef INET 7384 case AF_INET: 7385 { 7386 struct sockaddr_in *sin; 7387 7388 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 7389 if (sin == NULL) 7390 return (ENOMEM); 7391 sin->sin_family = AF_INET; 7392 sin->sin_len = sizeof(*sin); 7393 sin->sin_port = store.sin.sin_port; 7394 sin->sin_addr = store.sin.sin_addr; 7395 *addr = (struct sockaddr *)sin; 7396 break; 7397 } 7398 #endif 7399 #ifdef INET6 7400 case AF_INET6: 7401 { 7402 struct sockaddr_in6 *sin6; 7403 7404 SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); 7405 if (sin6 == NULL) 7406 return (ENOMEM); 7407 sin6->sin6_family = AF_INET6; 7408 sin6->sin6_len = sizeof(*sin6); 7409 sin6->sin6_port = store.sin6.sin6_port; 7410 sin6->sin6_addr = store.sin6.sin6_addr; 7411 if ((error = sa6_recoverscope(sin6)) != 0) { 7412 SCTP_FREE_SONAME(sin6); 7413 return (error); 7414 } 7415 *addr = (struct sockaddr *)sin6; 7416 break; 7417 } 7418 #endif 7419 default: 7420 /* TSNH */ 7421 break; 7422 } 7423 return (0); 7424 } 7425 7426 #ifdef INET 7427 int 7428 sctp_ingetaddr(struct socket *so, struct sockaddr **addr) 7429 { 7430 struct sockaddr_in *sin; 7431 uint32_t vrf_id; 7432 struct sctp_inpcb *inp; 7433 struct sctp_ifa *sctp_ifa; 7434 7435 /* 7436 * Do the malloc first in case it blocks. 7437 */ 7438 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 7439 if (sin == NULL) 7440 return (ENOMEM); 7441 sin->sin_family = AF_INET; 7442 sin->sin_len = sizeof(*sin); 7443 inp = (struct sctp_inpcb *)so->so_pcb; 7444 if (!inp) { 7445 SCTP_FREE_SONAME(sin); 7446 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7447 return (ECONNRESET); 7448 } 7449 SCTP_INP_RLOCK(inp); 7450 sin->sin_port = inp->sctp_lport; 7451 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 7452 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 7453 struct sctp_tcb *stcb; 7454 struct sockaddr_in *sin_a; 7455 struct sctp_nets *net; 7456 int fnd; 7457 7458 stcb = LIST_FIRST(&inp->sctp_asoc_list); 7459 if (stcb == NULL) { 7460 goto notConn; 7461 } 7462 fnd = 0; 7463 sin_a = NULL; 7464 SCTP_TCB_LOCK(stcb); 7465 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 7466 sin_a = (struct sockaddr_in *)&net->ro._l_addr; 7467 if (sin_a == NULL) 7468 /* this will make coverity happy */ 7469 continue; 7470 7471 if (sin_a->sin_family == AF_INET) { 7472 fnd = 1; 7473 break; 7474 } 7475 } 7476 if ((!fnd) || (sin_a == NULL)) { 7477 /* punt */ 7478 SCTP_TCB_UNLOCK(stcb); 7479 goto notConn; 7480 } 7481 7482 vrf_id = inp->def_vrf_id; 7483 sctp_ifa = sctp_source_address_selection(inp, 7484 stcb, 7485 (sctp_route_t *)&net->ro, 7486 net, 0, vrf_id); 7487 if (sctp_ifa) { 7488 sin->sin_addr = sctp_ifa->address.sin.sin_addr; 7489 sctp_free_ifa(sctp_ifa); 7490 } 7491 SCTP_TCB_UNLOCK(stcb); 7492 } else { 7493 /* For the bound all case you get back 0 */ 7494 notConn: 7495 sin->sin_addr.s_addr = 0; 7496 } 7497 7498 } else { 7499 /* Take the first IPv4 address in the list */ 7500 struct sctp_laddr *laddr; 7501 int fnd = 0; 7502 7503 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 7504 if (laddr->ifa->address.sa.sa_family == AF_INET) { 7505 struct sockaddr_in *sin_a; 7506 7507 sin_a = &laddr->ifa->address.sin; 7508 sin->sin_addr = sin_a->sin_addr; 7509 fnd = 1; 7510 break; 7511 } 7512 } 7513 if (!fnd) { 7514 SCTP_FREE_SONAME(sin); 7515 SCTP_INP_RUNLOCK(inp); 7516 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 7517 return (ENOENT); 7518 } 7519 } 7520 SCTP_INP_RUNLOCK(inp); 7521 (*addr) = (struct sockaddr *)sin; 7522 return (0); 7523 } 7524 7525 int 7526 sctp_peeraddr(struct socket *so, struct sockaddr **addr) 7527 { 7528 struct sockaddr_in *sin; 7529 int fnd; 7530 struct sockaddr_in *sin_a; 7531 struct sctp_inpcb *inp; 7532 struct sctp_tcb *stcb; 7533 struct sctp_nets *net; 7534 7535 /* Do the malloc first in case it blocks. */ 7536 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 7537 if (sin == NULL) 7538 return (ENOMEM); 7539 sin->sin_family = AF_INET; 7540 sin->sin_len = sizeof(*sin); 7541 7542 inp = (struct sctp_inpcb *)so->so_pcb; 7543 if ((inp == NULL) || 7544 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) { 7545 /* UDP type and listeners will drop out here */ 7546 SCTP_FREE_SONAME(sin); 7547 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 7548 return (ENOTCONN); 7549 } 7550 SCTP_INP_RLOCK(inp); 7551 stcb = LIST_FIRST(&inp->sctp_asoc_list); 7552 if (stcb) { 7553 SCTP_TCB_LOCK(stcb); 7554 } 7555 SCTP_INP_RUNLOCK(inp); 7556 if (stcb == NULL) { 7557 SCTP_FREE_SONAME(sin); 7558 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7559 return (ECONNRESET); 7560 } 7561 fnd = 0; 7562 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 7563 sin_a = (struct sockaddr_in *)&net->ro._l_addr; 7564 if (sin_a->sin_family == AF_INET) { 7565 fnd = 1; 7566 sin->sin_port = stcb->rport; 7567 sin->sin_addr = sin_a->sin_addr; 7568 break; 7569 } 7570 } 7571 SCTP_TCB_UNLOCK(stcb); 7572 if (!fnd) { 7573 /* No IPv4 address */ 7574 SCTP_FREE_SONAME(sin); 7575 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 7576 return (ENOENT); 7577 } 7578 (*addr) = (struct sockaddr *)sin; 7579 return (0); 7580 } 7581 7582 struct pr_usrreqs sctp_usrreqs = { 7583 .pru_abort = sctp_abort, 7584 .pru_accept = sctp_accept, 7585 .pru_attach = sctp_attach, 7586 .pru_bind = sctp_bind, 7587 .pru_connect = sctp_connect, 7588 .pru_control = in_control, 7589 .pru_close = sctp_close, 7590 .pru_detach = sctp_close, 7591 .pru_sopoll = sopoll_generic, 7592 .pru_flush = sctp_flush, 7593 .pru_disconnect = sctp_disconnect, 7594 .pru_listen = sctp_listen, 7595 .pru_peeraddr = sctp_peeraddr, 7596 .pru_send = sctp_sendm, 7597 .pru_shutdown = sctp_shutdown, 7598 .pru_sockaddr = sctp_ingetaddr, 7599 .pru_sosend = sctp_sosend, 7600 .pru_soreceive = sctp_soreceive 7601 }; 7602 #endif 7603