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