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