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