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