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