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