1 /*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * b) Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the distribution. 13 * 14 * c) Neither the name of Cisco Systems, Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* $KAME: sctp_usrreq.c,v 1.48 2005/03/07 23:26:08 itojun Exp $ */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 #include <netinet/sctp_os.h> 36 #include <sys/proc.h> 37 #include <netinet/sctp_pcb.h> 38 #include <netinet/sctp_header.h> 39 #include <netinet/sctp_var.h> 40 #if defined(INET6) 41 #endif 42 #include <netinet/sctp_sysctl.h> 43 #include <netinet/sctp_output.h> 44 #include <netinet/sctp_uio.h> 45 #include <netinet/sctp_asconf.h> 46 #include <netinet/sctputil.h> 47 #include <netinet/sctp_indata.h> 48 #include <netinet/sctp_timer.h> 49 #include <netinet/sctp_auth.h> 50 #include <netinet/sctp_bsd_addr.h> 51 #include <netinet/sctp_cc_functions.h> 52 53 54 55 56 void 57 sctp_init(void) 58 { 59 u_long sb_max_adj; 60 61 bzero(&SCTP_BASE_STATS, sizeof(struct sctpstat)); 62 63 /* Initialize and modify the sysctled variables */ 64 sctp_init_sysctls(); 65 if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE) 66 SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = (nmbclusters / 8); 67 /* 68 * Allow a user to take no more than 1/2 the number of clusters or 69 * the SB_MAX whichever is smaller for the send window. 70 */ 71 sb_max_adj = (u_long)((u_quad_t) (SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES)); 72 SCTP_BASE_SYSCTL(sctp_sendspace) = min(sb_max_adj, 73 (((uint32_t) nmbclusters / 2) * SCTP_DEFAULT_MAXSEGMENT)); 74 /* 75 * Now for the recv window, should we take the same amount? or 76 * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For 77 * now I will just copy. 78 */ 79 SCTP_BASE_SYSCTL(sctp_recvspace) = SCTP_BASE_SYSCTL(sctp_sendspace); 80 81 SCTP_BASE_VAR(first_time) = 0; 82 SCTP_BASE_VAR(sctp_pcb_initialized) = 0; 83 sctp_pcb_init(); 84 #if defined(SCTP_PACKET_LOGGING) 85 SCTP_BASE_VAR(packet_log_writers) = 0; 86 SCTP_BASE_VAR(packet_log_end) = 0; 87 bzero(&SCTP_BASE_VAR(packet_log_buffer), SCTP_PACKET_LOG_SIZE); 88 #endif 89 90 91 } 92 93 void 94 sctp_finish(void) 95 { 96 sctp_pcb_finish(); 97 } 98 99 100 101 void 102 sctp_pathmtu_adjustment(struct sctp_inpcb *inp, 103 struct sctp_tcb *stcb, 104 struct sctp_nets *net, 105 uint16_t nxtsz) 106 { 107 struct sctp_tmit_chunk *chk; 108 109 /* Adjust that too */ 110 stcb->asoc.smallest_mtu = nxtsz; 111 /* now off to subtract IP_DF flag if needed */ 112 #ifdef SCTP_PRINT_FOR_B_AND_M 113 SCTP_PRINTF("sctp_pathmtu_adjust called inp:%p stcb:%p net:%p nxtsz:%d\n", 114 inp, stcb, net, nxtsz); 115 #endif 116 TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) { 117 if ((chk->send_size + IP_HDR_SIZE) > nxtsz) { 118 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 119 } 120 } 121 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 122 if ((chk->send_size + IP_HDR_SIZE) > nxtsz) { 123 /* 124 * For this guy we also mark for immediate resend 125 * since we sent to big of chunk 126 */ 127 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 128 if (chk->sent != SCTP_DATAGRAM_RESEND) { 129 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 130 } 131 chk->sent = SCTP_DATAGRAM_RESEND; 132 chk->rec.data.doing_fast_retransmit = 0; 133 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) { 134 sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU, 135 chk->whoTo->flight_size, 136 chk->book_size, 137 (uintptr_t) chk->whoTo, 138 chk->rec.data.TSN_seq); 139 } 140 /* Clear any time so NO RTT is being done */ 141 chk->do_rtt = 0; 142 sctp_flight_size_decrease(chk); 143 sctp_total_flight_decrease(stcb, chk); 144 } 145 } 146 } 147 148 static void 149 sctp_notify_mbuf(struct sctp_inpcb *inp, 150 struct sctp_tcb *stcb, 151 struct sctp_nets *net, 152 struct ip *ip, 153 struct sctphdr *sh) 154 { 155 struct icmp *icmph; 156 int totsz, tmr_stopped = 0; 157 uint16_t nxtsz; 158 159 /* protection */ 160 if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 161 (ip == NULL) || (sh == NULL)) { 162 if (stcb != NULL) { 163 SCTP_TCB_UNLOCK(stcb); 164 } 165 return; 166 } 167 /* First job is to verify the vtag matches what I would send */ 168 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 169 SCTP_TCB_UNLOCK(stcb); 170 return; 171 } 172 icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) - 173 sizeof(struct ip))); 174 if (icmph->icmp_type != ICMP_UNREACH) { 175 /* We only care about unreachable */ 176 SCTP_TCB_UNLOCK(stcb); 177 return; 178 } 179 if (icmph->icmp_code != ICMP_UNREACH_NEEDFRAG) { 180 /* not a unreachable message due to frag. */ 181 SCTP_TCB_UNLOCK(stcb); 182 return; 183 } 184 totsz = ip->ip_len; 185 186 nxtsz = ntohs(icmph->icmp_nextmtu); 187 if (nxtsz == 0) { 188 /* 189 * old type router that does not tell us what the next size 190 * mtu is. Rats we will have to guess (in a educated fashion 191 * of course) 192 */ 193 nxtsz = find_next_best_mtu(totsz); 194 } 195 /* Stop any PMTU timer */ 196 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 197 tmr_stopped = 1; 198 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 199 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1); 200 } 201 /* Adjust destination size limit */ 202 if (net->mtu > nxtsz) { 203 net->mtu = nxtsz; 204 } 205 /* now what about the ep? */ 206 if (stcb->asoc.smallest_mtu > nxtsz) { 207 #ifdef SCTP_PRINT_FOR_B_AND_M 208 SCTP_PRINTF("notify_mbuf (ICMP) calls sctp_pathmtu_adjust mtu:%d\n", 209 nxtsz); 210 #endif 211 sctp_pathmtu_adjustment(inp, stcb, net, nxtsz); 212 } 213 if (tmr_stopped) 214 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 215 216 SCTP_TCB_UNLOCK(stcb); 217 } 218 219 220 void 221 sctp_notify(struct sctp_inpcb *inp, 222 struct ip *ip, 223 struct sctphdr *sh, 224 struct sockaddr *to, 225 struct sctp_tcb *stcb, 226 struct sctp_nets *net) 227 { 228 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 229 struct socket *so; 230 231 #endif 232 /* protection */ 233 int reason; 234 struct icmp *icmph; 235 236 237 if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 238 (sh == NULL) || (to == NULL)) { 239 if (stcb) 240 SCTP_TCB_UNLOCK(stcb); 241 return; 242 } 243 /* First job is to verify the vtag matches what I would send */ 244 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 245 SCTP_TCB_UNLOCK(stcb); 246 return; 247 } 248 icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) - 249 sizeof(struct ip))); 250 if (icmph->icmp_type != ICMP_UNREACH) { 251 /* We only care about unreachable */ 252 SCTP_TCB_UNLOCK(stcb); 253 return; 254 } 255 if ((icmph->icmp_code == ICMP_UNREACH_NET) || 256 (icmph->icmp_code == ICMP_UNREACH_HOST) || 257 (icmph->icmp_code == ICMP_UNREACH_NET_UNKNOWN) || 258 (icmph->icmp_code == ICMP_UNREACH_HOST_UNKNOWN) || 259 (icmph->icmp_code == ICMP_UNREACH_ISOLATED) || 260 (icmph->icmp_code == ICMP_UNREACH_NET_PROHIB) || 261 (icmph->icmp_code == ICMP_UNREACH_HOST_PROHIB) || 262 (icmph->icmp_code == ICMP_UNREACH_FILTER_PROHIB)) { 263 264 /* 265 * Hmm reachablity problems we must examine closely. If its 266 * not reachable, we may have lost a network. Or if there is 267 * NO protocol at the other end named SCTP. well we consider 268 * it a OOTB abort. 269 */ 270 if (net->dest_state & SCTP_ADDR_REACHABLE) { 271 /* Ok that destination is NOT reachable */ 272 SCTP_PRINTF("ICMP (thresh %d/%d) takes interface %p down\n", 273 net->error_count, 274 net->failure_threshold, 275 net); 276 277 net->dest_state &= ~SCTP_ADDR_REACHABLE; 278 net->dest_state |= SCTP_ADDR_NOT_REACHABLE; 279 /* 280 * JRS 5/14/07 - If a destination is unreachable, 281 * the PF bit is turned off. This allows an 282 * unambiguous use of the PF bit for destinations 283 * that are reachable but potentially failed. If the 284 * destination is set to the unreachable state, also 285 * set the destination to the PF state. 286 */ 287 /* 288 * Add debug message here if destination is not in 289 * PF state. 290 */ 291 /* Stop any running T3 timers here? */ 292 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) { 293 net->dest_state &= ~SCTP_ADDR_PF; 294 SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n", 295 net); 296 } 297 net->error_count = net->failure_threshold + 1; 298 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 299 stcb, SCTP_FAILED_THRESHOLD, 300 (void *)net, SCTP_SO_NOT_LOCKED); 301 } 302 SCTP_TCB_UNLOCK(stcb); 303 } else if ((icmph->icmp_code == ICMP_UNREACH_PROTOCOL) || 304 (icmph->icmp_code == ICMP_UNREACH_PORT)) { 305 /* 306 * Here the peer is either playing tricks on us, including 307 * an address that belongs to someone who does not support 308 * SCTP OR was a userland implementation that shutdown and 309 * now is dead. In either case treat it like a OOTB abort 310 * with no TCB 311 */ 312 reason = SCTP_PEER_FAULTY; 313 sctp_abort_notification(stcb, reason, SCTP_SO_NOT_LOCKED); 314 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 315 so = SCTP_INP_SO(inp); 316 atomic_add_int(&stcb->asoc.refcnt, 1); 317 SCTP_TCB_UNLOCK(stcb); 318 SCTP_SOCKET_LOCK(so, 1); 319 SCTP_TCB_LOCK(stcb); 320 atomic_subtract_int(&stcb->asoc.refcnt, 1); 321 #endif 322 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2); 323 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 324 SCTP_SOCKET_UNLOCK(so, 1); 325 /* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed. */ 326 #endif 327 /* no need to unlock here, since the TCB is gone */ 328 } else { 329 SCTP_TCB_UNLOCK(stcb); 330 } 331 } 332 333 void 334 sctp_ctlinput(cmd, sa, vip) 335 int cmd; 336 struct sockaddr *sa; 337 void *vip; 338 { 339 struct ip *ip = vip; 340 struct sctphdr *sh; 341 uint32_t vrf_id; 342 343 /* FIX, for non-bsd is this right? */ 344 vrf_id = SCTP_DEFAULT_VRFID; 345 if (sa->sa_family != AF_INET || 346 ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) { 347 return; 348 } 349 if (PRC_IS_REDIRECT(cmd)) { 350 ip = 0; 351 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) { 352 return; 353 } 354 if (ip) { 355 struct sctp_inpcb *inp = NULL; 356 struct sctp_tcb *stcb = NULL; 357 struct sctp_nets *net = NULL; 358 struct sockaddr_in to, from; 359 360 sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 361 bzero(&to, sizeof(to)); 362 bzero(&from, sizeof(from)); 363 from.sin_family = to.sin_family = AF_INET; 364 from.sin_len = to.sin_len = sizeof(to); 365 from.sin_port = sh->src_port; 366 from.sin_addr = ip->ip_src; 367 to.sin_port = sh->dest_port; 368 to.sin_addr = ip->ip_dst; 369 370 /* 371 * 'to' holds the dest of the packet that failed to be sent. 372 * 'from' holds our local endpoint address. Thus we reverse 373 * the to and the from in the lookup. 374 */ 375 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&from, 376 (struct sockaddr *)&to, 377 &inp, &net, 1, vrf_id); 378 if (stcb != NULL && inp && (inp->sctp_socket != NULL)) { 379 if (cmd != PRC_MSGSIZE) { 380 sctp_notify(inp, ip, sh, 381 (struct sockaddr *)&to, stcb, 382 net); 383 } else { 384 /* handle possible ICMP size messages */ 385 sctp_notify_mbuf(inp, stcb, net, ip, sh); 386 } 387 } else { 388 if ((stcb == NULL) && (inp != NULL)) { 389 /* reduce ref-count */ 390 SCTP_INP_WLOCK(inp); 391 SCTP_INP_DECR_REF(inp); 392 SCTP_INP_WUNLOCK(inp); 393 } 394 } 395 } 396 return; 397 } 398 399 static int 400 sctp_getcred(SYSCTL_HANDLER_ARGS) 401 { 402 struct xucred xuc; 403 struct sockaddr_in addrs[2]; 404 struct sctp_inpcb *inp; 405 struct sctp_nets *net; 406 struct sctp_tcb *stcb; 407 int error; 408 uint32_t vrf_id; 409 410 /* FIX, for non-bsd is this right? */ 411 vrf_id = SCTP_DEFAULT_VRFID; 412 413 error = priv_check(req->td, PRIV_NETINET_GETCRED); 414 415 if (error) 416 return (error); 417 418 error = SYSCTL_IN(req, addrs, sizeof(addrs)); 419 if (error) 420 return (error); 421 422 stcb = sctp_findassociation_addr_sa(sintosa(&addrs[0]), 423 sintosa(&addrs[1]), 424 &inp, &net, 1, vrf_id); 425 if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) { 426 if ((inp != NULL) && (stcb == NULL)) { 427 /* reduce ref-count */ 428 SCTP_INP_WLOCK(inp); 429 SCTP_INP_DECR_REF(inp); 430 goto cred_can_cont; 431 } 432 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 433 error = ENOENT; 434 goto out; 435 } 436 SCTP_TCB_UNLOCK(stcb); 437 /* 438 * We use the write lock here, only since in the error leg we need 439 * it. If we used RLOCK, then we would have to 440 * wlock/decr/unlock/rlock. Which in theory could create a hole. 441 * Better to use higher wlock. 442 */ 443 SCTP_INP_WLOCK(inp); 444 cred_can_cont: 445 error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket); 446 if (error) { 447 SCTP_INP_WUNLOCK(inp); 448 goto out; 449 } 450 cru2x(inp->sctp_socket->so_cred, &xuc); 451 SCTP_INP_WUNLOCK(inp); 452 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 453 out: 454 return (error); 455 } 456 457 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW, 458 0, 0, sctp_getcred, "S,ucred", "Get the ucred of a SCTP connection"); 459 460 461 static void 462 sctp_abort(struct socket *so) 463 { 464 struct sctp_inpcb *inp; 465 uint32_t flags; 466 467 inp = (struct sctp_inpcb *)so->so_pcb; 468 if (inp == 0) { 469 return; 470 } 471 sctp_must_try_again: 472 flags = inp->sctp_flags; 473 #ifdef SCTP_LOG_CLOSING 474 sctp_log_closing(inp, NULL, 17); 475 #endif 476 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 477 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 478 #ifdef SCTP_LOG_CLOSING 479 sctp_log_closing(inp, NULL, 16); 480 #endif 481 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 482 SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 483 SOCK_LOCK(so); 484 SCTP_SB_CLEAR(so->so_snd); 485 /* 486 * same for the rcv ones, they are only here for the 487 * accounting/select. 488 */ 489 SCTP_SB_CLEAR(so->so_rcv); 490 491 /* Now null out the reference, we are completely detached. */ 492 so->so_pcb = NULL; 493 SOCK_UNLOCK(so); 494 } else { 495 flags = inp->sctp_flags; 496 if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 497 goto sctp_must_try_again; 498 } 499 } 500 return; 501 } 502 503 static int 504 sctp_attach(struct socket *so, int proto, struct thread *p) 505 { 506 struct sctp_inpcb *inp; 507 struct inpcb *ip_inp; 508 int error; 509 uint32_t vrf_id = SCTP_DEFAULT_VRFID; 510 511 #ifdef IPSEC 512 uint32_t flags; 513 514 #endif 515 inp = (struct sctp_inpcb *)so->so_pcb; 516 if (inp != 0) { 517 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 518 return EINVAL; 519 } 520 error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); 521 if (error) { 522 return error; 523 } 524 error = sctp_inpcb_alloc(so, vrf_id); 525 if (error) { 526 return error; 527 } 528 inp = (struct sctp_inpcb *)so->so_pcb; 529 SCTP_INP_WLOCK(inp); 530 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */ 531 ip_inp = &inp->ip_inp.inp; 532 ip_inp->inp_vflag |= INP_IPV4; 533 ip_inp->inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl); 534 #ifdef IPSEC 535 error = ipsec_init_policy(so, &ip_inp->inp_sp); 536 #ifdef SCTP_LOG_CLOSING 537 sctp_log_closing(inp, NULL, 17); 538 #endif 539 if (error != 0) { 540 flags = inp->sctp_flags; 541 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 542 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 543 #ifdef SCTP_LOG_CLOSING 544 sctp_log_closing(inp, NULL, 15); 545 #endif 546 SCTP_INP_WUNLOCK(inp); 547 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 548 SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 549 } else { 550 SCTP_INP_WUNLOCK(inp); 551 } 552 return error; 553 } 554 #endif /* IPSEC */ 555 SCTP_INP_WUNLOCK(inp); 556 return 0; 557 } 558 559 static int 560 sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p) 561 { 562 struct sctp_inpcb *inp = NULL; 563 int error; 564 565 #ifdef INET6 566 if (addr && addr->sa_family != AF_INET) { 567 /* must be a v4 address! */ 568 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 569 return EINVAL; 570 } 571 #endif /* INET6 */ 572 if (addr && (addr->sa_len != sizeof(struct sockaddr_in))) { 573 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 574 return EINVAL; 575 } 576 inp = (struct sctp_inpcb *)so->so_pcb; 577 if (inp == 0) { 578 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 579 return EINVAL; 580 } 581 error = sctp_inpcb_bind(so, addr, NULL, p); 582 return error; 583 } 584 585 void 586 sctp_close(struct socket *so) 587 { 588 struct sctp_inpcb *inp; 589 uint32_t flags; 590 591 inp = (struct sctp_inpcb *)so->so_pcb; 592 if (inp == 0) 593 return; 594 595 /* 596 * Inform all the lower layer assoc that we are done. 597 */ 598 sctp_must_try_again: 599 flags = inp->sctp_flags; 600 #ifdef SCTP_LOG_CLOSING 601 sctp_log_closing(inp, NULL, 17); 602 #endif 603 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 604 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 605 if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) || 606 (so->so_rcv.sb_cc > 0)) { 607 #ifdef SCTP_LOG_CLOSING 608 sctp_log_closing(inp, NULL, 13); 609 #endif 610 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 611 SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 612 } else { 613 #ifdef SCTP_LOG_CLOSING 614 sctp_log_closing(inp, NULL, 14); 615 #endif 616 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE, 617 SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 618 } 619 /* 620 * The socket is now detached, no matter what the state of 621 * the SCTP association. 622 */ 623 SOCK_LOCK(so); 624 SCTP_SB_CLEAR(so->so_snd); 625 /* 626 * same for the rcv ones, they are only here for the 627 * accounting/select. 628 */ 629 SCTP_SB_CLEAR(so->so_rcv); 630 631 /* Now null out the reference, we are completely detached. */ 632 so->so_pcb = NULL; 633 SOCK_UNLOCK(so); 634 } else { 635 flags = inp->sctp_flags; 636 if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 637 goto sctp_must_try_again; 638 } 639 } 640 return; 641 } 642 643 644 int 645 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 646 struct mbuf *control, struct thread *p); 647 648 649 int 650 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 651 struct mbuf *control, struct thread *p) 652 { 653 struct sctp_inpcb *inp; 654 int error; 655 656 inp = (struct sctp_inpcb *)so->so_pcb; 657 if (inp == 0) { 658 if (control) { 659 sctp_m_freem(control); 660 control = NULL; 661 } 662 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 663 sctp_m_freem(m); 664 return EINVAL; 665 } 666 /* Got to have an to address if we are NOT a connected socket */ 667 if ((addr == NULL) && 668 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) || 669 (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) 670 ) { 671 goto connected_type; 672 } else if (addr == NULL) { 673 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ); 674 error = EDESTADDRREQ; 675 sctp_m_freem(m); 676 if (control) { 677 sctp_m_freem(control); 678 control = NULL; 679 } 680 return (error); 681 } 682 #ifdef INET6 683 if (addr->sa_family != AF_INET) { 684 /* must be a v4 address! */ 685 SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ); 686 sctp_m_freem(m); 687 if (control) { 688 sctp_m_freem(control); 689 control = NULL; 690 } 691 error = EDESTADDRREQ; 692 return EDESTADDRREQ; 693 } 694 #endif /* INET6 */ 695 connected_type: 696 /* now what about control */ 697 if (control) { 698 if (inp->control) { 699 SCTP_PRINTF("huh? control set?\n"); 700 sctp_m_freem(inp->control); 701 inp->control = NULL; 702 } 703 inp->control = control; 704 } 705 /* Place the data */ 706 if (inp->pkt) { 707 SCTP_BUF_NEXT(inp->pkt_last) = m; 708 inp->pkt_last = m; 709 } else { 710 inp->pkt_last = inp->pkt = m; 711 } 712 if ( 713 /* FreeBSD uses a flag passed */ 714 ((flags & PRUS_MORETOCOME) == 0) 715 ) { 716 /* 717 * note with the current version this code will only be used 718 * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for 719 * re-defining sosend to use the sctp_sosend. One can 720 * optionally switch back to this code (by changing back the 721 * definitions) but this is not advisable. This code is used 722 * by FreeBSD when sending a file with sendfile() though. 723 */ 724 int ret; 725 726 ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags); 727 inp->pkt = NULL; 728 inp->control = NULL; 729 return (ret); 730 } else { 731 return (0); 732 } 733 } 734 735 int 736 sctp_disconnect(struct socket *so) 737 { 738 struct sctp_inpcb *inp; 739 740 inp = (struct sctp_inpcb *)so->so_pcb; 741 if (inp == NULL) { 742 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 743 return (ENOTCONN); 744 } 745 SCTP_INP_RLOCK(inp); 746 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 747 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 748 if (SCTP_LIST_EMPTY(&inp->sctp_asoc_list)) { 749 /* No connection */ 750 SCTP_INP_RUNLOCK(inp); 751 return (0); 752 } else { 753 struct sctp_association *asoc; 754 struct sctp_tcb *stcb; 755 756 stcb = LIST_FIRST(&inp->sctp_asoc_list); 757 if (stcb == NULL) { 758 SCTP_INP_RUNLOCK(inp); 759 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 760 return (EINVAL); 761 } 762 SCTP_TCB_LOCK(stcb); 763 asoc = &stcb->asoc; 764 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 765 /* We are about to be freed, out of here */ 766 SCTP_TCB_UNLOCK(stcb); 767 SCTP_INP_RUNLOCK(inp); 768 return (0); 769 } 770 if (((so->so_options & SO_LINGER) && 771 (so->so_linger == 0)) || 772 (so->so_rcv.sb_cc > 0)) { 773 if (SCTP_GET_STATE(asoc) != 774 SCTP_STATE_COOKIE_WAIT) { 775 /* Left with Data unread */ 776 struct mbuf *err; 777 778 err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_DONTWAIT, 1, MT_DATA); 779 if (err) { 780 /* 781 * Fill in the user 782 * initiated abort 783 */ 784 struct sctp_paramhdr *ph; 785 786 ph = mtod(err, struct sctp_paramhdr *); 787 SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr); 788 ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); 789 ph->param_length = htons(SCTP_BUF_LEN(err)); 790 } 791 #if defined(SCTP_PANIC_ON_ABORT) 792 panic("disconnect does an abort"); 793 #endif 794 sctp_send_abort_tcb(stcb, err, SCTP_SO_LOCKED); 795 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 796 } 797 SCTP_INP_RUNLOCK(inp); 798 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 799 (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 800 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 801 } 802 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3); 803 /* No unlock tcb assoc is gone */ 804 return (0); 805 } 806 if (TAILQ_EMPTY(&asoc->send_queue) && 807 TAILQ_EMPTY(&asoc->sent_queue) && 808 (asoc->stream_queue_cnt == 0)) { 809 /* there is nothing queued to send, so done */ 810 if (asoc->locked_on_sending) { 811 goto abort_anyway; 812 } 813 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) && 814 (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) { 815 /* only send SHUTDOWN 1st time thru */ 816 sctp_stop_timers_for_shutdown(stcb); 817 sctp_send_shutdown(stcb, 818 stcb->asoc.primary_destination); 819 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED); 820 if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) || 821 (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 822 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 823 } 824 SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT); 825 SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING); 826 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 827 stcb->sctp_ep, stcb, 828 asoc->primary_destination); 829 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 830 stcb->sctp_ep, stcb, 831 asoc->primary_destination); 832 } 833 } else { 834 /* 835 * we still got (or just got) data to send, 836 * so set SHUTDOWN_PENDING 837 */ 838 /* 839 * XXX sockets draft says that SCTP_EOF 840 * should be sent with no data. currently, 841 * we will allow user data to be sent first 842 * and move to SHUTDOWN-PENDING 843 */ 844 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING; 845 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, 846 asoc->primary_destination); 847 if (asoc->locked_on_sending) { 848 /* Locked to send out the data */ 849 struct sctp_stream_queue_pending *sp; 850 851 sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead); 852 if (sp == NULL) { 853 SCTP_PRINTF("Error, sp is NULL, locked on sending is non-null strm:%d\n", 854 asoc->locked_on_sending->stream_no); 855 } else { 856 if ((sp->length == 0) && (sp->msg_is_complete == 0)) 857 asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT; 858 } 859 } 860 if (TAILQ_EMPTY(&asoc->send_queue) && 861 TAILQ_EMPTY(&asoc->sent_queue) && 862 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 863 struct mbuf *op_err; 864 865 abort_anyway: 866 op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), 867 0, M_DONTWAIT, 1, MT_DATA); 868 if (op_err) { 869 /* 870 * Fill in the user 871 * initiated abort 872 */ 873 struct sctp_paramhdr *ph; 874 uint32_t *ippp; 875 876 SCTP_BUF_LEN(op_err) = 877 (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)); 878 ph = mtod(op_err, 879 struct sctp_paramhdr *); 880 ph->param_type = htons( 881 SCTP_CAUSE_USER_INITIATED_ABT); 882 ph->param_length = htons(SCTP_BUF_LEN(op_err)); 883 ippp = (uint32_t *) (ph + 1); 884 *ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4); 885 } 886 #if defined(SCTP_PANIC_ON_ABORT) 887 panic("disconnect does an abort"); 888 #endif 889 890 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4; 891 sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED); 892 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 893 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 894 (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 895 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 896 } 897 SCTP_INP_RUNLOCK(inp); 898 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5); 899 return (0); 900 } else { 901 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED); 902 } 903 } 904 SCTP_TCB_UNLOCK(stcb); 905 SCTP_INP_RUNLOCK(inp); 906 return (0); 907 } 908 /* not reached */ 909 } else { 910 /* UDP model does not support this */ 911 SCTP_INP_RUNLOCK(inp); 912 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 913 return EOPNOTSUPP; 914 } 915 } 916 917 int 918 sctp_flush(struct socket *so, int how) 919 { 920 /* 921 * We will just clear out the values and let subsequent close clear 922 * out the data, if any. Note if the user did a shutdown(SHUT_RD) 923 * they will not be able to read the data, the socket will block 924 * that from happening. 925 */ 926 if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) { 927 /* 928 * First make sure the sb will be happy, we don't use these 929 * except maybe the count 930 */ 931 so->so_rcv.sb_cc = 0; 932 so->so_rcv.sb_mbcnt = 0; 933 so->so_rcv.sb_mb = NULL; 934 } 935 if ((how == PRU_FLUSH_WR) || (how == PRU_FLUSH_RDWR)) { 936 /* 937 * First make sure the sb will be happy, we don't use these 938 * except maybe the count 939 */ 940 so->so_snd.sb_cc = 0; 941 so->so_snd.sb_mbcnt = 0; 942 so->so_snd.sb_mb = NULL; 943 944 } 945 return (0); 946 } 947 948 int 949 sctp_shutdown(struct socket *so) 950 { 951 struct sctp_inpcb *inp; 952 953 inp = (struct sctp_inpcb *)so->so_pcb; 954 if (inp == 0) { 955 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 956 return EINVAL; 957 } 958 SCTP_INP_RLOCK(inp); 959 /* For UDP model this is a invalid call */ 960 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 961 /* Restore the flags that the soshutdown took away. */ 962 so->so_rcv.sb_state &= ~SBS_CANTRCVMORE; 963 /* This proc will wakeup for read and do nothing (I hope) */ 964 SCTP_INP_RUNLOCK(inp); 965 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 966 return (EOPNOTSUPP); 967 } 968 /* 969 * Ok if we reach here its the TCP model and it is either a SHUT_WR 970 * or SHUT_RDWR. This means we put the shutdown flag against it. 971 */ 972 { 973 struct sctp_tcb *stcb; 974 struct sctp_association *asoc; 975 976 socantsendmore(so); 977 978 stcb = LIST_FIRST(&inp->sctp_asoc_list); 979 if (stcb == NULL) { 980 /* 981 * Ok we hit the case that the shutdown call was 982 * made after an abort or something. Nothing to do 983 * now. 984 */ 985 SCTP_INP_RUNLOCK(inp); 986 return (0); 987 } 988 SCTP_TCB_LOCK(stcb); 989 asoc = &stcb->asoc; 990 if (TAILQ_EMPTY(&asoc->send_queue) && 991 TAILQ_EMPTY(&asoc->sent_queue) && 992 (asoc->stream_queue_cnt == 0)) { 993 if (asoc->locked_on_sending) { 994 goto abort_anyway; 995 } 996 /* there is nothing queued to send, so I'm done... */ 997 if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) { 998 /* only send SHUTDOWN the first time through */ 999 sctp_stop_timers_for_shutdown(stcb); 1000 sctp_send_shutdown(stcb, 1001 stcb->asoc.primary_destination); 1002 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED); 1003 if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) || 1004 (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 1005 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 1006 } 1007 SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT); 1008 SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING); 1009 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 1010 stcb->sctp_ep, stcb, 1011 asoc->primary_destination); 1012 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 1013 stcb->sctp_ep, stcb, 1014 asoc->primary_destination); 1015 } 1016 } else { 1017 /* 1018 * we still got (or just got) data to send, so set 1019 * SHUTDOWN_PENDING 1020 */ 1021 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING; 1022 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, 1023 asoc->primary_destination); 1024 1025 if (asoc->locked_on_sending) { 1026 /* Locked to send out the data */ 1027 struct sctp_stream_queue_pending *sp; 1028 1029 sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead); 1030 if (sp == NULL) { 1031 SCTP_PRINTF("Error, sp is NULL, locked on sending is non-null strm:%d\n", 1032 asoc->locked_on_sending->stream_no); 1033 } else { 1034 if ((sp->length == 0) && (sp->msg_is_complete == 0)) { 1035 asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT; 1036 } 1037 } 1038 } 1039 if (TAILQ_EMPTY(&asoc->send_queue) && 1040 TAILQ_EMPTY(&asoc->sent_queue) && 1041 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 1042 struct mbuf *op_err; 1043 1044 abort_anyway: 1045 op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), 1046 0, M_DONTWAIT, 1, MT_DATA); 1047 if (op_err) { 1048 /* Fill in the user initiated abort */ 1049 struct sctp_paramhdr *ph; 1050 uint32_t *ippp; 1051 1052 SCTP_BUF_LEN(op_err) = 1053 sizeof(struct sctp_paramhdr) + sizeof(uint32_t); 1054 ph = mtod(op_err, 1055 struct sctp_paramhdr *); 1056 ph->param_type = htons( 1057 SCTP_CAUSE_USER_INITIATED_ABT); 1058 ph->param_length = htons(SCTP_BUF_LEN(op_err)); 1059 ippp = (uint32_t *) (ph + 1); 1060 *ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6); 1061 } 1062 #if defined(SCTP_PANIC_ON_ABORT) 1063 panic("shutdown does an abort"); 1064 #endif 1065 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6; 1066 sctp_abort_an_association(stcb->sctp_ep, stcb, 1067 SCTP_RESPONSE_TO_USER_REQ, 1068 op_err, SCTP_SO_LOCKED); 1069 goto skip_unlock; 1070 } else { 1071 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED); 1072 } 1073 } 1074 SCTP_TCB_UNLOCK(stcb); 1075 } 1076 skip_unlock: 1077 SCTP_INP_RUNLOCK(inp); 1078 return 0; 1079 } 1080 1081 /* 1082 * copies a "user" presentable address and removes embedded scope, etc. 1083 * returns 0 on success, 1 on error 1084 */ 1085 static uint32_t 1086 sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa) 1087 { 1088 #ifdef INET6 1089 struct sockaddr_in6 lsa6; 1090 1091 sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa, 1092 &lsa6); 1093 #endif 1094 memcpy(ss, sa, sa->sa_len); 1095 return (0); 1096 } 1097 1098 1099 1100 /* 1101 * NOTE: assumes addr lock is held 1102 */ 1103 static size_t 1104 sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, 1105 struct sctp_tcb *stcb, 1106 size_t limit, 1107 struct sockaddr_storage *sas, 1108 uint32_t vrf_id) 1109 { 1110 struct sctp_ifn *sctp_ifn; 1111 struct sctp_ifa *sctp_ifa; 1112 int loopback_scope, ipv4_local_scope, local_scope, site_scope; 1113 size_t actual; 1114 int ipv4_addr_legal, ipv6_addr_legal; 1115 struct sctp_vrf *vrf; 1116 1117 actual = 0; 1118 if (limit <= 0) 1119 return (actual); 1120 1121 if (stcb) { 1122 /* Turn on all the appropriate scope */ 1123 loopback_scope = stcb->asoc.loopback_scope; 1124 ipv4_local_scope = stcb->asoc.ipv4_local_scope; 1125 local_scope = stcb->asoc.local_scope; 1126 site_scope = stcb->asoc.site_scope; 1127 } else { 1128 /* Turn on ALL scope, since we look at the EP */ 1129 loopback_scope = ipv4_local_scope = local_scope = 1130 site_scope = 1; 1131 } 1132 ipv4_addr_legal = ipv6_addr_legal = 0; 1133 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1134 ipv6_addr_legal = 1; 1135 if (SCTP_IPV6_V6ONLY(inp) == 0) { 1136 ipv4_addr_legal = 1; 1137 } 1138 } else { 1139 ipv4_addr_legal = 1; 1140 } 1141 vrf = sctp_find_vrf(vrf_id); 1142 if (vrf == NULL) { 1143 return (0); 1144 } 1145 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1146 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 1147 if ((loopback_scope == 0) && 1148 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { 1149 /* Skip loopback if loopback_scope not set */ 1150 continue; 1151 } 1152 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 1153 if (stcb) { 1154 /* 1155 * For the BOUND-ALL case, the list 1156 * associated with a TCB is Always 1157 * considered a reverse list.. i.e. 1158 * it lists addresses that are NOT 1159 * part of the association. If this 1160 * is one of those we must skip it. 1161 */ 1162 if (sctp_is_addr_restricted(stcb, 1163 sctp_ifa)) { 1164 continue; 1165 } 1166 } 1167 switch (sctp_ifa->address.sa.sa_family) { 1168 case AF_INET: 1169 if (ipv4_addr_legal) { 1170 struct sockaddr_in *sin; 1171 1172 sin = (struct sockaddr_in *)&sctp_ifa->address.sa; 1173 if (sin->sin_addr.s_addr == 0) { 1174 /* 1175 * we skip 1176 * unspecifed 1177 * addresses 1178 */ 1179 continue; 1180 } 1181 if ((ipv4_local_scope == 0) && 1182 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 1183 continue; 1184 } 1185 #ifdef INET6 1186 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 1187 in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas); 1188 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1189 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6)); 1190 actual += sizeof(struct sockaddr_in6); 1191 } else { 1192 #endif 1193 memcpy(sas, sin, sizeof(*sin)); 1194 ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 1195 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin)); 1196 actual += sizeof(*sin); 1197 #ifdef INET6 1198 } 1199 #endif 1200 if (actual >= limit) { 1201 return (actual); 1202 } 1203 } else { 1204 continue; 1205 } 1206 break; 1207 #ifdef INET6 1208 case AF_INET6: 1209 if (ipv6_addr_legal) { 1210 struct sockaddr_in6 *sin6; 1211 1212 sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa; 1213 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1214 /* 1215 * we skip 1216 * unspecifed 1217 * addresses 1218 */ 1219 continue; 1220 } 1221 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 1222 if (local_scope == 0) 1223 continue; 1224 if (sin6->sin6_scope_id == 0) { 1225 if (sa6_recoverscope(sin6) != 0) 1226 /* 1227 * 1228 * bad 1229 * 1230 * li 1231 * nk 1232 * 1233 * loc 1234 * al 1235 * 1236 * add 1237 * re 1238 * ss 1239 * */ 1240 continue; 1241 } 1242 } 1243 if ((site_scope == 0) && 1244 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 1245 continue; 1246 } 1247 memcpy(sas, sin6, sizeof(*sin6)); 1248 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1249 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6)); 1250 actual += sizeof(*sin6); 1251 if (actual >= limit) { 1252 return (actual); 1253 } 1254 } else { 1255 continue; 1256 } 1257 break; 1258 #endif 1259 default: 1260 /* TSNH */ 1261 break; 1262 } 1263 } 1264 } 1265 } else { 1266 struct sctp_laddr *laddr; 1267 1268 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1269 if (stcb) { 1270 if (sctp_is_addr_restricted(stcb, laddr->ifa)) { 1271 continue; 1272 } 1273 } 1274 if (sctp_fill_user_address(sas, &laddr->ifa->address.sa)) 1275 continue; 1276 1277 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1278 sas = (struct sockaddr_storage *)((caddr_t)sas + 1279 laddr->ifa->address.sa.sa_len); 1280 actual += laddr->ifa->address.sa.sa_len; 1281 if (actual >= limit) { 1282 return (actual); 1283 } 1284 } 1285 } 1286 return (actual); 1287 } 1288 1289 static size_t 1290 sctp_fill_up_addresses(struct sctp_inpcb *inp, 1291 struct sctp_tcb *stcb, 1292 size_t limit, 1293 struct sockaddr_storage *sas) 1294 { 1295 size_t size = 0; 1296 1297 SCTP_IPI_ADDR_RLOCK(); 1298 /* fill up addresses for the endpoint's default vrf */ 1299 size = sctp_fill_up_addresses_vrf(inp, stcb, limit, sas, 1300 inp->def_vrf_id); 1301 SCTP_IPI_ADDR_RUNLOCK(); 1302 return (size); 1303 } 1304 1305 /* 1306 * NOTE: assumes addr lock is held 1307 */ 1308 static int 1309 sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id) 1310 { 1311 int cnt = 0; 1312 struct sctp_vrf *vrf = NULL; 1313 1314 /* 1315 * In both sub-set bound an bound_all cases we return the MAXIMUM 1316 * number of addresses that you COULD get. In reality the sub-set 1317 * bound may have an exclusion list for a given TCB OR in the 1318 * bound-all case a TCB may NOT include the loopback or other 1319 * addresses as well. 1320 */ 1321 vrf = sctp_find_vrf(vrf_id); 1322 if (vrf == NULL) { 1323 return (0); 1324 } 1325 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1326 struct sctp_ifn *sctp_ifn; 1327 struct sctp_ifa *sctp_ifa; 1328 1329 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 1330 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 1331 /* Count them if they are the right type */ 1332 if (sctp_ifa->address.sa.sa_family == AF_INET) { 1333 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 1334 cnt += sizeof(struct sockaddr_in6); 1335 else 1336 cnt += sizeof(struct sockaddr_in); 1337 1338 } else if (sctp_ifa->address.sa.sa_family == AF_INET6) 1339 cnt += sizeof(struct sockaddr_in6); 1340 } 1341 } 1342 } else { 1343 struct sctp_laddr *laddr; 1344 1345 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1346 if (laddr->ifa->address.sa.sa_family == AF_INET) { 1347 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 1348 cnt += sizeof(struct sockaddr_in6); 1349 else 1350 cnt += sizeof(struct sockaddr_in); 1351 1352 } else if (laddr->ifa->address.sa.sa_family == AF_INET6) 1353 cnt += sizeof(struct sockaddr_in6); 1354 } 1355 } 1356 return (cnt); 1357 } 1358 1359 static int 1360 sctp_count_max_addresses(struct sctp_inpcb *inp) 1361 { 1362 int cnt = 0; 1363 1364 SCTP_IPI_ADDR_RLOCK(); 1365 /* count addresses for the endpoint's default VRF */ 1366 cnt = sctp_count_max_addresses_vrf(inp, inp->def_vrf_id); 1367 SCTP_IPI_ADDR_RUNLOCK(); 1368 return (cnt); 1369 } 1370 1371 static int 1372 sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval, 1373 size_t optsize, void *p, int delay) 1374 { 1375 int error = 0; 1376 int creat_lock_on = 0; 1377 struct sctp_tcb *stcb = NULL; 1378 struct sockaddr *sa; 1379 int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr; 1380 int added = 0; 1381 uint32_t vrf_id; 1382 int bad_addresses = 0; 1383 sctp_assoc_t *a_id; 1384 1385 SCTPDBG(SCTP_DEBUG_PCB1, "Connectx called\n"); 1386 1387 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 1388 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 1389 /* We are already connected AND the TCP model */ 1390 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 1391 return (EADDRINUSE); 1392 } 1393 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 1394 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 1395 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1396 return (EINVAL); 1397 } 1398 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 1399 SCTP_INP_RLOCK(inp); 1400 stcb = LIST_FIRST(&inp->sctp_asoc_list); 1401 SCTP_INP_RUNLOCK(inp); 1402 } 1403 if (stcb) { 1404 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 1405 return (EALREADY); 1406 } 1407 SCTP_INP_INCR_REF(inp); 1408 SCTP_ASOC_CREATE_LOCK(inp); 1409 creat_lock_on = 1; 1410 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 1411 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 1412 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 1413 error = EFAULT; 1414 goto out_now; 1415 } 1416 totaddrp = (int *)optval; 1417 totaddr = *totaddrp; 1418 sa = (struct sockaddr *)(totaddrp + 1); 1419 stcb = sctp_connectx_helper_find(inp, sa, &totaddr, &num_v4, &num_v6, &error, (optsize - sizeof(int)), &bad_addresses); 1420 if ((stcb != NULL) || bad_addresses) { 1421 /* Already have or am bring up an association */ 1422 SCTP_ASOC_CREATE_UNLOCK(inp); 1423 creat_lock_on = 0; 1424 if (stcb) 1425 SCTP_TCB_UNLOCK(stcb); 1426 if (bad_addresses == 0) { 1427 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 1428 error = EALREADY; 1429 } 1430 goto out_now; 1431 } 1432 #ifdef INET6 1433 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 1434 (num_v6 > 0)) { 1435 error = EINVAL; 1436 goto out_now; 1437 } 1438 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 1439 (num_v4 > 0)) { 1440 struct in6pcb *inp6; 1441 1442 inp6 = (struct in6pcb *)inp; 1443 if (SCTP_IPV6_V6ONLY(inp6)) { 1444 /* 1445 * if IPV6_V6ONLY flag, ignore connections destined 1446 * to a v4 addr or v4-mapped addr 1447 */ 1448 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1449 error = EINVAL; 1450 goto out_now; 1451 } 1452 } 1453 #endif /* INET6 */ 1454 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 1455 SCTP_PCB_FLAGS_UNBOUND) { 1456 /* Bind a ephemeral port */ 1457 error = sctp_inpcb_bind(so, NULL, NULL, p); 1458 if (error) { 1459 goto out_now; 1460 } 1461 } 1462 /* FIX ME: do we want to pass in a vrf on the connect call? */ 1463 vrf_id = inp->def_vrf_id; 1464 1465 1466 /* We are GOOD to go */ 1467 stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0, vrf_id, 1468 (struct thread *)p 1469 ); 1470 if (stcb == NULL) { 1471 /* Gak! no memory */ 1472 goto out_now; 1473 } 1474 SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 1475 /* move to second address */ 1476 if (sa->sa_family == AF_INET) 1477 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in)); 1478 else 1479 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6)); 1480 1481 error = 0; 1482 added = sctp_connectx_helper_add(stcb, sa, (totaddr - 1), &error); 1483 /* Fill in the return id */ 1484 if (error) { 1485 (void)sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_12); 1486 goto out_now; 1487 } 1488 a_id = (sctp_assoc_t *) optval; 1489 *a_id = sctp_get_associd(stcb); 1490 1491 /* initialize authentication parameters for the assoc */ 1492 sctp_initialize_auth_params(inp, stcb); 1493 1494 if (delay) { 1495 /* doing delayed connection */ 1496 stcb->asoc.delayed_connection = 1; 1497 sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination); 1498 } else { 1499 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 1500 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 1501 } 1502 SCTP_TCB_UNLOCK(stcb); 1503 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 1504 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 1505 /* Set the connected flag so we can queue data */ 1506 soisconnecting(so); 1507 } 1508 out_now: 1509 if (creat_lock_on) { 1510 SCTP_ASOC_CREATE_UNLOCK(inp); 1511 } 1512 SCTP_INP_DECR_REF(inp); 1513 return error; 1514 } 1515 1516 #define SCTP_FIND_STCB(inp, stcb, assoc_id) { \ 1517 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||\ 1518 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { \ 1519 SCTP_INP_RLOCK(inp); \ 1520 stcb = LIST_FIRST(&inp->sctp_asoc_list); \ 1521 if (stcb) { \ 1522 SCTP_TCB_LOCK(stcb); \ 1523 } \ 1524 SCTP_INP_RUNLOCK(inp); \ 1525 } else if (assoc_id != 0) { \ 1526 stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \ 1527 if (stcb == NULL) { \ 1528 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \ 1529 error = ENOENT; \ 1530 break; \ 1531 } \ 1532 } else { \ 1533 stcb = NULL; \ 1534 } \ 1535 } 1536 1537 1538 #define SCTP_CHECK_AND_CAST(destp, srcp, type, size) {\ 1539 if (size < sizeof(type)) { \ 1540 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); \ 1541 error = EINVAL; \ 1542 break; \ 1543 } else { \ 1544 destp = (type *)srcp; \ 1545 } \ 1546 } 1547 1548 static int 1549 sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, 1550 void *p) 1551 { 1552 struct sctp_inpcb *inp = NULL; 1553 int error, val = 0; 1554 struct sctp_tcb *stcb = NULL; 1555 1556 if (optval == NULL) { 1557 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1558 return (EINVAL); 1559 } 1560 inp = (struct sctp_inpcb *)so->so_pcb; 1561 if (inp == 0) { 1562 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1563 return EINVAL; 1564 } 1565 error = 0; 1566 1567 switch (optname) { 1568 case SCTP_NODELAY: 1569 case SCTP_AUTOCLOSE: 1570 case SCTP_EXPLICIT_EOR: 1571 case SCTP_AUTO_ASCONF: 1572 case SCTP_DISABLE_FRAGMENTS: 1573 case SCTP_I_WANT_MAPPED_V4_ADDR: 1574 case SCTP_USE_EXT_RCVINFO: 1575 SCTP_INP_RLOCK(inp); 1576 switch (optname) { 1577 case SCTP_DISABLE_FRAGMENTS: 1578 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT); 1579 break; 1580 case SCTP_I_WANT_MAPPED_V4_ADDR: 1581 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4); 1582 break; 1583 case SCTP_AUTO_ASCONF: 1584 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1585 /* only valid for bound all sockets */ 1586 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 1587 } else { 1588 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1589 error = EINVAL; 1590 goto flags_out; 1591 } 1592 break; 1593 case SCTP_EXPLICIT_EOR: 1594 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); 1595 break; 1596 case SCTP_NODELAY: 1597 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY); 1598 break; 1599 case SCTP_USE_EXT_RCVINFO: 1600 val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO); 1601 break; 1602 case SCTP_AUTOCLOSE: 1603 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) 1604 val = TICKS_TO_SEC(inp->sctp_ep.auto_close_time); 1605 else 1606 val = 0; 1607 break; 1608 1609 default: 1610 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 1611 error = ENOPROTOOPT; 1612 } /* end switch (sopt->sopt_name) */ 1613 if (optname != SCTP_AUTOCLOSE) { 1614 /* make it an "on/off" value */ 1615 val = (val != 0); 1616 } 1617 if (*optsize < sizeof(val)) { 1618 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1619 error = EINVAL; 1620 } 1621 flags_out: 1622 SCTP_INP_RUNLOCK(inp); 1623 if (error == 0) { 1624 /* return the option value */ 1625 *(int *)optval = val; 1626 *optsize = sizeof(val); 1627 } 1628 break; 1629 case SCTP_GET_PACKET_LOG: 1630 { 1631 #ifdef SCTP_PACKET_LOGGING 1632 uint8_t *target; 1633 int ret; 1634 1635 SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize); 1636 ret = sctp_copy_out_packet_log(target, (int)*optsize); 1637 *optsize = ret; 1638 #else 1639 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 1640 error = EOPNOTSUPP; 1641 #endif 1642 break; 1643 } 1644 case SCTP_REUSE_PORT: 1645 { 1646 uint32_t *value; 1647 1648 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 1649 /* Can't do this for a 1-m socket */ 1650 error = EINVAL; 1651 break; 1652 } 1653 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1654 *value = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 1655 *optsize = sizeof(uint32_t); 1656 } 1657 break; 1658 case SCTP_PARTIAL_DELIVERY_POINT: 1659 { 1660 uint32_t *value; 1661 1662 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1663 *value = inp->partial_delivery_point; 1664 *optsize = sizeof(uint32_t); 1665 } 1666 break; 1667 case SCTP_FRAGMENT_INTERLEAVE: 1668 { 1669 uint32_t *value; 1670 1671 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1672 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) { 1673 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) { 1674 *value = SCTP_FRAG_LEVEL_2; 1675 } else { 1676 *value = SCTP_FRAG_LEVEL_1; 1677 } 1678 } else { 1679 *value = SCTP_FRAG_LEVEL_0; 1680 } 1681 *optsize = sizeof(uint32_t); 1682 } 1683 break; 1684 case SCTP_CMT_ON_OFF: 1685 { 1686 struct sctp_assoc_value *av; 1687 1688 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1689 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) { 1690 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1691 if (stcb) { 1692 av->assoc_value = stcb->asoc.sctp_cmt_on_off; 1693 SCTP_TCB_UNLOCK(stcb); 1694 1695 } else { 1696 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 1697 error = ENOTCONN; 1698 } 1699 } else { 1700 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 1701 error = ENOPROTOOPT; 1702 } 1703 *optsize = sizeof(*av); 1704 } 1705 break; 1706 /* JRS - Get socket option for pluggable congestion control */ 1707 case SCTP_PLUGGABLE_CC: 1708 { 1709 struct sctp_assoc_value *av; 1710 1711 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1712 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1713 if (stcb) { 1714 av->assoc_value = stcb->asoc.congestion_control_module; 1715 SCTP_TCB_UNLOCK(stcb); 1716 } else { 1717 av->assoc_value = inp->sctp_ep.sctp_default_cc_module; 1718 } 1719 *optsize = sizeof(*av); 1720 } 1721 break; 1722 case SCTP_GET_ADDR_LEN: 1723 { 1724 struct sctp_assoc_value *av; 1725 1726 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1727 error = EINVAL; 1728 #ifdef INET 1729 if (av->assoc_value == AF_INET) { 1730 av->assoc_value = sizeof(struct sockaddr_in); 1731 error = 0; 1732 } 1733 #endif 1734 #ifdef INET6 1735 if (av->assoc_value == AF_INET6) { 1736 av->assoc_value = sizeof(struct sockaddr_in6); 1737 error = 0; 1738 } 1739 #endif 1740 if (error) { 1741 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1742 } 1743 *optsize = sizeof(*av); 1744 } 1745 break; 1746 case SCTP_GET_ASSOC_NUMBER: 1747 { 1748 uint32_t *value, cnt; 1749 1750 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1751 cnt = 0; 1752 SCTP_INP_RLOCK(inp); 1753 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 1754 cnt++; 1755 } 1756 SCTP_INP_RUNLOCK(inp); 1757 *value = cnt; 1758 *optsize = sizeof(uint32_t); 1759 } 1760 break; 1761 1762 case SCTP_GET_ASSOC_ID_LIST: 1763 { 1764 struct sctp_assoc_ids *ids; 1765 unsigned int at, limit; 1766 1767 SCTP_CHECK_AND_CAST(ids, optval, struct sctp_assoc_ids, *optsize); 1768 at = 0; 1769 limit = *optsize / sizeof(sctp_assoc_t); 1770 SCTP_INP_RLOCK(inp); 1771 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 1772 if (at < limit) { 1773 ids->gaids_assoc_id[at++] = sctp_get_associd(stcb); 1774 } else { 1775 error = EINVAL; 1776 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1777 break; 1778 } 1779 } 1780 SCTP_INP_RUNLOCK(inp); 1781 *optsize = at * sizeof(sctp_assoc_t); 1782 } 1783 break; 1784 case SCTP_CONTEXT: 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 1791 if (stcb) { 1792 av->assoc_value = stcb->asoc.context; 1793 SCTP_TCB_UNLOCK(stcb); 1794 } else { 1795 SCTP_INP_RLOCK(inp); 1796 av->assoc_value = inp->sctp_context; 1797 SCTP_INP_RUNLOCK(inp); 1798 } 1799 *optsize = sizeof(*av); 1800 } 1801 break; 1802 case SCTP_VRF_ID: 1803 { 1804 uint32_t *default_vrfid; 1805 1806 SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, *optsize); 1807 *default_vrfid = inp->def_vrf_id; 1808 break; 1809 } 1810 case SCTP_GET_ASOC_VRF: 1811 { 1812 struct sctp_assoc_value *id; 1813 1814 SCTP_CHECK_AND_CAST(id, optval, struct sctp_assoc_value, *optsize); 1815 SCTP_FIND_STCB(inp, stcb, id->assoc_id); 1816 if (stcb == NULL) { 1817 error = EINVAL; 1818 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 1819 break; 1820 } 1821 id->assoc_value = stcb->asoc.vrf_id; 1822 break; 1823 } 1824 case SCTP_GET_VRF_IDS: 1825 { 1826 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 1827 error = EOPNOTSUPP; 1828 break; 1829 } 1830 case SCTP_GET_NONCE_VALUES: 1831 { 1832 struct sctp_get_nonce_values *gnv; 1833 1834 SCTP_CHECK_AND_CAST(gnv, optval, struct sctp_get_nonce_values, *optsize); 1835 SCTP_FIND_STCB(inp, stcb, gnv->gn_assoc_id); 1836 1837 if (stcb) { 1838 gnv->gn_peers_tag = stcb->asoc.peer_vtag; 1839 gnv->gn_local_tag = stcb->asoc.my_vtag; 1840 SCTP_TCB_UNLOCK(stcb); 1841 } else { 1842 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 1843 error = ENOTCONN; 1844 } 1845 *optsize = sizeof(*gnv); 1846 } 1847 break; 1848 case SCTP_DELAYED_SACK: 1849 { 1850 struct sctp_sack_info *sack; 1851 1852 SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, *optsize); 1853 SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 1854 if (stcb) { 1855 sack->sack_delay = stcb->asoc.delayed_ack; 1856 sack->sack_freq = stcb->asoc.sack_freq; 1857 SCTP_TCB_UNLOCK(stcb); 1858 } else { 1859 SCTP_INP_RLOCK(inp); 1860 sack->sack_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 1861 sack->sack_freq = inp->sctp_ep.sctp_sack_freq; 1862 SCTP_INP_RUNLOCK(inp); 1863 } 1864 *optsize = sizeof(*sack); 1865 } 1866 break; 1867 1868 case SCTP_GET_SNDBUF_USE: 1869 { 1870 struct sctp_sockstat *ss; 1871 1872 SCTP_CHECK_AND_CAST(ss, optval, struct sctp_sockstat, *optsize); 1873 SCTP_FIND_STCB(inp, stcb, ss->ss_assoc_id); 1874 1875 if (stcb) { 1876 ss->ss_total_sndbuf = stcb->asoc.total_output_queue_size; 1877 ss->ss_total_recv_buf = (stcb->asoc.size_on_reasm_queue + 1878 stcb->asoc.size_on_all_streams); 1879 SCTP_TCB_UNLOCK(stcb); 1880 } else { 1881 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 1882 error = ENOTCONN; 1883 } 1884 *optsize = sizeof(struct sctp_sockstat); 1885 } 1886 break; 1887 case SCTP_MAX_BURST: 1888 { 1889 uint8_t *value; 1890 1891 SCTP_CHECK_AND_CAST(value, optval, uint8_t, *optsize); 1892 1893 SCTP_INP_RLOCK(inp); 1894 *value = inp->sctp_ep.max_burst; 1895 SCTP_INP_RUNLOCK(inp); 1896 *optsize = sizeof(uint8_t); 1897 } 1898 break; 1899 case SCTP_MAXSEG: 1900 { 1901 struct sctp_assoc_value *av; 1902 int ovh; 1903 1904 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 1905 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 1906 1907 if (stcb) { 1908 av->assoc_value = sctp_get_frag_point(stcb, &stcb->asoc); 1909 SCTP_TCB_UNLOCK(stcb); 1910 } else { 1911 SCTP_INP_RLOCK(inp); 1912 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1913 ovh = SCTP_MED_OVERHEAD; 1914 } else { 1915 ovh = SCTP_MED_V4_OVERHEAD; 1916 } 1917 if (inp->sctp_frag_point >= SCTP_DEFAULT_MAXSEGMENT) 1918 av->assoc_value = 0; 1919 else 1920 av->assoc_value = inp->sctp_frag_point - ovh; 1921 SCTP_INP_RUNLOCK(inp); 1922 } 1923 *optsize = sizeof(struct sctp_assoc_value); 1924 } 1925 break; 1926 case SCTP_GET_STAT_LOG: 1927 error = sctp_fill_stat_log(optval, optsize); 1928 break; 1929 case SCTP_EVENTS: 1930 { 1931 struct sctp_event_subscribe *events; 1932 1933 SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, *optsize); 1934 memset(events, 0, sizeof(*events)); 1935 SCTP_INP_RLOCK(inp); 1936 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT)) 1937 events->sctp_data_io_event = 1; 1938 1939 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT)) 1940 events->sctp_association_event = 1; 1941 1942 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT)) 1943 events->sctp_address_event = 1; 1944 1945 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) 1946 events->sctp_send_failure_event = 1; 1947 1948 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR)) 1949 events->sctp_peer_error_event = 1; 1950 1951 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) 1952 events->sctp_shutdown_event = 1; 1953 1954 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT)) 1955 events->sctp_partial_delivery_event = 1; 1956 1957 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) 1958 events->sctp_adaptation_layer_event = 1; 1959 1960 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT)) 1961 events->sctp_authentication_event = 1; 1962 1963 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT)) 1964 events->sctp_stream_reset_events = 1; 1965 SCTP_INP_RUNLOCK(inp); 1966 *optsize = sizeof(struct sctp_event_subscribe); 1967 } 1968 break; 1969 1970 case SCTP_ADAPTATION_LAYER: 1971 { 1972 uint32_t *value; 1973 1974 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1975 1976 SCTP_INP_RLOCK(inp); 1977 *value = inp->sctp_ep.adaptation_layer_indicator; 1978 SCTP_INP_RUNLOCK(inp); 1979 *optsize = sizeof(uint32_t); 1980 } 1981 break; 1982 case SCTP_SET_INITIAL_DBG_SEQ: 1983 { 1984 uint32_t *value; 1985 1986 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1987 SCTP_INP_RLOCK(inp); 1988 *value = inp->sctp_ep.initial_sequence_debug; 1989 SCTP_INP_RUNLOCK(inp); 1990 *optsize = sizeof(uint32_t); 1991 } 1992 break; 1993 case SCTP_GET_LOCAL_ADDR_SIZE: 1994 { 1995 uint32_t *value; 1996 1997 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 1998 SCTP_INP_RLOCK(inp); 1999 *value = sctp_count_max_addresses(inp); 2000 SCTP_INP_RUNLOCK(inp); 2001 *optsize = sizeof(uint32_t); 2002 } 2003 break; 2004 case SCTP_GET_REMOTE_ADDR_SIZE: 2005 { 2006 uint32_t *value; 2007 size_t size; 2008 struct sctp_nets *net; 2009 2010 SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 2011 /* FIXME MT: change to sctp_assoc_value? */ 2012 SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) * value); 2013 2014 if (stcb) { 2015 size = 0; 2016 /* Count the sizes */ 2017 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2018 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) || 2019 (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) { 2020 size += sizeof(struct sockaddr_in6); 2021 } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) { 2022 size += sizeof(struct sockaddr_in); 2023 } else { 2024 /* huh */ 2025 break; 2026 } 2027 } 2028 SCTP_TCB_UNLOCK(stcb); 2029 *value = (uint32_t) size; 2030 } else { 2031 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 2032 error = ENOTCONN; 2033 } 2034 *optsize = sizeof(uint32_t); 2035 } 2036 break; 2037 case SCTP_GET_PEER_ADDRESSES: 2038 /* 2039 * Get the address information, an array is passed in to 2040 * fill up we pack it. 2041 */ 2042 { 2043 size_t cpsz, left; 2044 struct sockaddr_storage *sas; 2045 struct sctp_nets *net; 2046 struct sctp_getaddresses *saddr; 2047 2048 SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 2049 SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 2050 2051 if (stcb) { 2052 left = (*optsize) - sizeof(struct sctp_getaddresses); 2053 *optsize = sizeof(struct sctp_getaddresses); 2054 sas = (struct sockaddr_storage *)&saddr->addr[0]; 2055 2056 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2057 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) || 2058 (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) { 2059 cpsz = sizeof(struct sockaddr_in6); 2060 } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) { 2061 cpsz = sizeof(struct sockaddr_in); 2062 } else { 2063 /* huh */ 2064 break; 2065 } 2066 if (left < cpsz) { 2067 /* not enough room. */ 2068 break; 2069 } 2070 #ifdef INET6 2071 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) && 2072 (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) { 2073 /* Must map the address */ 2074 in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr, 2075 (struct sockaddr_in6 *)sas); 2076 } else { 2077 #endif 2078 memcpy(sas, &net->ro._l_addr, cpsz); 2079 #ifdef INET6 2080 } 2081 #endif 2082 ((struct sockaddr_in *)sas)->sin_port = stcb->rport; 2083 2084 sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz); 2085 left -= cpsz; 2086 *optsize += cpsz; 2087 } 2088 SCTP_TCB_UNLOCK(stcb); 2089 } else { 2090 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 2091 error = ENOENT; 2092 } 2093 } 2094 break; 2095 case SCTP_GET_LOCAL_ADDRESSES: 2096 { 2097 size_t limit, actual; 2098 struct sockaddr_storage *sas; 2099 struct sctp_getaddresses *saddr; 2100 2101 SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 2102 SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 2103 2104 sas = (struct sockaddr_storage *)&saddr->addr[0]; 2105 limit = *optsize - sizeof(sctp_assoc_t); 2106 actual = sctp_fill_up_addresses(inp, stcb, limit, sas); 2107 if (stcb) { 2108 SCTP_TCB_UNLOCK(stcb); 2109 } 2110 *optsize = sizeof(struct sockaddr_storage) + actual; 2111 } 2112 break; 2113 case SCTP_PEER_ADDR_PARAMS: 2114 { 2115 struct sctp_paddrparams *paddrp; 2116 struct sctp_nets *net; 2117 2118 SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize); 2119 SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 2120 2121 net = NULL; 2122 if (stcb) { 2123 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 2124 } else { 2125 /* 2126 * We increment here since 2127 * sctp_findassociation_ep_addr() wil do a 2128 * decrement if it finds the stcb as long as 2129 * the locked tcb (last argument) is NOT a 2130 * TCB.. aka NULL. 2131 */ 2132 SCTP_INP_INCR_REF(inp); 2133 stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddrp->spp_address, &net, NULL, NULL); 2134 if (stcb == NULL) { 2135 SCTP_INP_DECR_REF(inp); 2136 } 2137 } 2138 if (stcb && (net == NULL)) { 2139 struct sockaddr *sa; 2140 2141 sa = (struct sockaddr *)&paddrp->spp_address; 2142 if (sa->sa_family == AF_INET) { 2143 struct sockaddr_in *sin; 2144 2145 sin = (struct sockaddr_in *)sa; 2146 if (sin->sin_addr.s_addr) { 2147 error = EINVAL; 2148 SCTP_TCB_UNLOCK(stcb); 2149 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2150 break; 2151 } 2152 } else if (sa->sa_family == AF_INET6) { 2153 struct sockaddr_in6 *sin6; 2154 2155 sin6 = (struct sockaddr_in6 *)sa; 2156 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 2157 error = EINVAL; 2158 SCTP_TCB_UNLOCK(stcb); 2159 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2160 break; 2161 } 2162 } else { 2163 error = EAFNOSUPPORT; 2164 SCTP_TCB_UNLOCK(stcb); 2165 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2166 break; 2167 } 2168 } 2169 if (stcb) { 2170 /* Applys to the specific association */ 2171 paddrp->spp_flags = 0; 2172 if (net) { 2173 int ovh; 2174 2175 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 2176 ovh = SCTP_MED_OVERHEAD; 2177 } else { 2178 ovh = SCTP_MED_V4_OVERHEAD; 2179 } 2180 2181 2182 paddrp->spp_pathmaxrxt = net->failure_threshold; 2183 paddrp->spp_pathmtu = net->mtu - ovh; 2184 /* get flags for HB */ 2185 if (net->dest_state & SCTP_ADDR_NOHB) 2186 paddrp->spp_flags |= SPP_HB_DISABLE; 2187 else 2188 paddrp->spp_flags |= SPP_HB_ENABLE; 2189 /* get flags for PMTU */ 2190 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 2191 paddrp->spp_flags |= SPP_PMTUD_ENABLE; 2192 } else { 2193 paddrp->spp_flags |= SPP_PMTUD_DISABLE; 2194 } 2195 #ifdef INET 2196 if (net->ro._l_addr.sin.sin_family == AF_INET) { 2197 paddrp->spp_ipv4_tos = net->tos_flowlabel & 0x000000fc; 2198 paddrp->spp_flags |= SPP_IPV4_TOS; 2199 } 2200 #endif 2201 #ifdef INET6 2202 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) { 2203 paddrp->spp_ipv6_flowlabel = net->tos_flowlabel; 2204 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2205 } 2206 #endif 2207 } else { 2208 /* 2209 * No destination so return default 2210 * value 2211 */ 2212 int cnt = 0; 2213 2214 paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure; 2215 paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc); 2216 #ifdef INET 2217 paddrp->spp_ipv4_tos = stcb->asoc.default_tos & 0x000000fc; 2218 paddrp->spp_flags |= SPP_IPV4_TOS; 2219 #endif 2220 #ifdef INET6 2221 paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel; 2222 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2223 #endif 2224 /* default settings should be these */ 2225 if (stcb->asoc.hb_is_disabled == 0) { 2226 paddrp->spp_flags |= SPP_HB_ENABLE; 2227 } else { 2228 paddrp->spp_flags |= SPP_HB_DISABLE; 2229 } 2230 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2231 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 2232 cnt++; 2233 } 2234 } 2235 if (cnt) { 2236 paddrp->spp_flags |= SPP_PMTUD_ENABLE; 2237 } 2238 } 2239 paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay; 2240 paddrp->spp_assoc_id = sctp_get_associd(stcb); 2241 SCTP_TCB_UNLOCK(stcb); 2242 } else { 2243 /* Use endpoint defaults */ 2244 SCTP_INP_RLOCK(inp); 2245 paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure; 2246 paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 2247 paddrp->spp_assoc_id = (sctp_assoc_t) 0; 2248 /* get inp's default */ 2249 #ifdef INET 2250 paddrp->spp_ipv4_tos = inp->ip_inp.inp.inp_ip_tos; 2251 paddrp->spp_flags |= SPP_IPV4_TOS; 2252 #endif 2253 #ifdef INET6 2254 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 2255 paddrp->spp_ipv6_flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo; 2256 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2257 } 2258 #endif 2259 /* can't return this */ 2260 paddrp->spp_pathmtu = 0; 2261 2262 /* default behavior, no stcb */ 2263 paddrp->spp_flags = SPP_PMTUD_ENABLE; 2264 2265 if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { 2266 paddrp->spp_flags |= SPP_HB_ENABLE; 2267 } else { 2268 paddrp->spp_flags |= SPP_HB_DISABLE; 2269 } 2270 SCTP_INP_RUNLOCK(inp); 2271 } 2272 *optsize = sizeof(struct sctp_paddrparams); 2273 } 2274 break; 2275 case SCTP_GET_PEER_ADDR_INFO: 2276 { 2277 struct sctp_paddrinfo *paddri; 2278 struct sctp_nets *net; 2279 2280 SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize); 2281 SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id); 2282 2283 net = NULL; 2284 if (stcb) { 2285 net = sctp_findnet(stcb, (struct sockaddr *)&paddri->spinfo_address); 2286 } else { 2287 /* 2288 * We increment here since 2289 * sctp_findassociation_ep_addr() wil do a 2290 * decrement if it finds the stcb as long as 2291 * the locked tcb (last argument) is NOT a 2292 * TCB.. aka NULL. 2293 */ 2294 SCTP_INP_INCR_REF(inp); 2295 stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddri->spinfo_address, &net, NULL, NULL); 2296 if (stcb == NULL) { 2297 SCTP_INP_DECR_REF(inp); 2298 } 2299 } 2300 2301 if ((stcb) && (net)) { 2302 paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK | SCTP_ADDR_NOHB); 2303 paddri->spinfo_cwnd = net->cwnd; 2304 paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1; 2305 paddri->spinfo_rto = net->RTO; 2306 paddri->spinfo_assoc_id = sctp_get_associd(stcb); 2307 SCTP_TCB_UNLOCK(stcb); 2308 } else { 2309 if (stcb) { 2310 SCTP_TCB_UNLOCK(stcb); 2311 } 2312 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 2313 error = ENOENT; 2314 } 2315 *optsize = sizeof(struct sctp_paddrinfo); 2316 } 2317 break; 2318 case SCTP_PCB_STATUS: 2319 { 2320 struct sctp_pcbinfo *spcb; 2321 2322 SCTP_CHECK_AND_CAST(spcb, optval, struct sctp_pcbinfo, *optsize); 2323 sctp_fill_pcbinfo(spcb); 2324 *optsize = sizeof(struct sctp_pcbinfo); 2325 } 2326 break; 2327 2328 case SCTP_STATUS: 2329 { 2330 struct sctp_nets *net; 2331 struct sctp_status *sstat; 2332 2333 SCTP_CHECK_AND_CAST(sstat, optval, struct sctp_status, *optsize); 2334 SCTP_FIND_STCB(inp, stcb, sstat->sstat_assoc_id); 2335 2336 if (stcb == NULL) { 2337 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2338 error = EINVAL; 2339 break; 2340 } 2341 /* 2342 * I think passing the state is fine since 2343 * sctp_constants.h will be available to the user 2344 * land. 2345 */ 2346 sstat->sstat_state = stcb->asoc.state; 2347 sstat->sstat_assoc_id = sctp_get_associd(stcb); 2348 sstat->sstat_rwnd = stcb->asoc.peers_rwnd; 2349 sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt; 2350 /* 2351 * We can't include chunks that have been passed to 2352 * the socket layer. Only things in queue. 2353 */ 2354 sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue + 2355 stcb->asoc.cnt_on_all_streams); 2356 2357 2358 sstat->sstat_instrms = stcb->asoc.streamincnt; 2359 sstat->sstat_outstrms = stcb->asoc.streamoutcnt; 2360 sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc); 2361 memcpy(&sstat->sstat_primary.spinfo_address, 2362 &stcb->asoc.primary_destination->ro._l_addr, 2363 ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len); 2364 net = stcb->asoc.primary_destination; 2365 ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport; 2366 /* 2367 * Again the user can get info from sctp_constants.h 2368 * for what the state of the network is. 2369 */ 2370 sstat->sstat_primary.spinfo_state = net->dest_state & SCTP_REACHABLE_MASK; 2371 sstat->sstat_primary.spinfo_cwnd = net->cwnd; 2372 sstat->sstat_primary.spinfo_srtt = net->lastsa; 2373 sstat->sstat_primary.spinfo_rto = net->RTO; 2374 sstat->sstat_primary.spinfo_mtu = net->mtu; 2375 sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb); 2376 SCTP_TCB_UNLOCK(stcb); 2377 *optsize = sizeof(*sstat); 2378 } 2379 break; 2380 case SCTP_RTOINFO: 2381 { 2382 struct sctp_rtoinfo *srto; 2383 2384 SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, *optsize); 2385 SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 2386 2387 if (stcb) { 2388 srto->srto_initial = stcb->asoc.initial_rto; 2389 srto->srto_max = stcb->asoc.maxrto; 2390 srto->srto_min = stcb->asoc.minrto; 2391 SCTP_TCB_UNLOCK(stcb); 2392 } else { 2393 SCTP_INP_RLOCK(inp); 2394 srto->srto_initial = inp->sctp_ep.initial_rto; 2395 srto->srto_max = inp->sctp_ep.sctp_maxrto; 2396 srto->srto_min = inp->sctp_ep.sctp_minrto; 2397 SCTP_INP_RUNLOCK(inp); 2398 } 2399 *optsize = sizeof(*srto); 2400 } 2401 break; 2402 case SCTP_ASSOCINFO: 2403 { 2404 struct sctp_assocparams *sasoc; 2405 uint32_t oldval; 2406 2407 SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, *optsize); 2408 SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 2409 2410 if (stcb) { 2411 oldval = sasoc->sasoc_cookie_life; 2412 sasoc->sasoc_cookie_life = TICKS_TO_MSEC(stcb->asoc.cookie_life); 2413 sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times; 2414 sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets; 2415 sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd; 2416 sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd; 2417 SCTP_TCB_UNLOCK(stcb); 2418 } else { 2419 SCTP_INP_RLOCK(inp); 2420 sasoc->sasoc_cookie_life = TICKS_TO_MSEC(inp->sctp_ep.def_cookie_life); 2421 sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times; 2422 sasoc->sasoc_number_peer_destinations = 0; 2423 sasoc->sasoc_peer_rwnd = 0; 2424 sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv); 2425 SCTP_INP_RUNLOCK(inp); 2426 } 2427 *optsize = sizeof(*sasoc); 2428 } 2429 break; 2430 case SCTP_DEFAULT_SEND_PARAM: 2431 { 2432 struct sctp_sndrcvinfo *s_info; 2433 2434 SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, *optsize); 2435 SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 2436 2437 if (stcb) { 2438 memcpy(s_info, &stcb->asoc.def_send, sizeof(stcb->asoc.def_send)); 2439 SCTP_TCB_UNLOCK(stcb); 2440 } else { 2441 SCTP_INP_RLOCK(inp); 2442 memcpy(s_info, &inp->def_send, sizeof(inp->def_send)); 2443 SCTP_INP_RUNLOCK(inp); 2444 } 2445 *optsize = sizeof(*s_info); 2446 } 2447 break; 2448 case SCTP_INITMSG: 2449 { 2450 struct sctp_initmsg *sinit; 2451 2452 SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, *optsize); 2453 SCTP_INP_RLOCK(inp); 2454 sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count; 2455 sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome; 2456 sinit->sinit_max_attempts = inp->sctp_ep.max_init_times; 2457 sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max; 2458 SCTP_INP_RUNLOCK(inp); 2459 *optsize = sizeof(*sinit); 2460 } 2461 break; 2462 case SCTP_PRIMARY_ADDR: 2463 /* we allow a "get" operation on this */ 2464 { 2465 struct sctp_setprim *ssp; 2466 2467 SCTP_CHECK_AND_CAST(ssp, optval, struct sctp_setprim, *optsize); 2468 SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id); 2469 2470 if (stcb) { 2471 /* simply copy out the sockaddr_storage... */ 2472 int len; 2473 2474 len = *optsize; 2475 if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len) 2476 len = stcb->asoc.primary_destination->ro._l_addr.sa.sa_len; 2477 2478 memcpy(&ssp->ssp_addr, 2479 &stcb->asoc.primary_destination->ro._l_addr, 2480 len); 2481 SCTP_TCB_UNLOCK(stcb); 2482 } else { 2483 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2484 error = EINVAL; 2485 } 2486 *optsize = sizeof(*ssp); 2487 } 2488 break; 2489 2490 case SCTP_HMAC_IDENT: 2491 { 2492 struct sctp_hmacalgo *shmac; 2493 sctp_hmaclist_t *hmaclist; 2494 uint32_t size; 2495 int i; 2496 2497 SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize); 2498 2499 SCTP_INP_RLOCK(inp); 2500 hmaclist = inp->sctp_ep.local_hmacs; 2501 if (hmaclist == NULL) { 2502 /* no HMACs to return */ 2503 *optsize = sizeof(*shmac); 2504 SCTP_INP_RUNLOCK(inp); 2505 break; 2506 } 2507 /* is there room for all of the hmac ids? */ 2508 size = sizeof(*shmac) + (hmaclist->num_algo * 2509 sizeof(shmac->shmac_idents[0])); 2510 if ((size_t)(*optsize) < size) { 2511 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2512 error = EINVAL; 2513 SCTP_INP_RUNLOCK(inp); 2514 break; 2515 } 2516 /* copy in the list */ 2517 shmac->shmac_number_of_idents = hmaclist->num_algo; 2518 for (i = 0; i < hmaclist->num_algo; i++) { 2519 shmac->shmac_idents[i] = hmaclist->hmac[i]; 2520 } 2521 SCTP_INP_RUNLOCK(inp); 2522 *optsize = size; 2523 break; 2524 } 2525 case SCTP_AUTH_ACTIVE_KEY: 2526 { 2527 struct sctp_authkeyid *scact; 2528 2529 SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, *optsize); 2530 SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 2531 2532 if (stcb) { 2533 /* get the active key on the assoc */ 2534 scact->scact_keynumber = stcb->asoc.authinfo.assoc_keyid; 2535 SCTP_TCB_UNLOCK(stcb); 2536 } else { 2537 /* get the endpoint active key */ 2538 SCTP_INP_RLOCK(inp); 2539 scact->scact_keynumber = inp->sctp_ep.default_keyid; 2540 SCTP_INP_RUNLOCK(inp); 2541 } 2542 *optsize = sizeof(*scact); 2543 break; 2544 } 2545 case SCTP_LOCAL_AUTH_CHUNKS: 2546 { 2547 struct sctp_authchunks *sac; 2548 sctp_auth_chklist_t *chklist = NULL; 2549 size_t size = 0; 2550 2551 SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 2552 SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 2553 2554 if (stcb) { 2555 /* get off the assoc */ 2556 chklist = stcb->asoc.local_auth_chunks; 2557 /* is there enough space? */ 2558 size = sctp_auth_get_chklist_size(chklist); 2559 if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 2560 error = EINVAL; 2561 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2562 } else { 2563 /* copy in the chunks */ 2564 (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 2565 } 2566 SCTP_TCB_UNLOCK(stcb); 2567 } else { 2568 /* get off the endpoint */ 2569 SCTP_INP_RLOCK(inp); 2570 chklist = inp->sctp_ep.local_auth_chunks; 2571 /* is there enough space? */ 2572 size = sctp_auth_get_chklist_size(chklist); 2573 if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 2574 error = EINVAL; 2575 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2576 } else { 2577 /* copy in the chunks */ 2578 (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 2579 } 2580 SCTP_INP_RUNLOCK(inp); 2581 } 2582 *optsize = sizeof(struct sctp_authchunks) + size; 2583 break; 2584 } 2585 case SCTP_PEER_AUTH_CHUNKS: 2586 { 2587 struct sctp_authchunks *sac; 2588 sctp_auth_chklist_t *chklist = NULL; 2589 size_t size = 0; 2590 2591 SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 2592 SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 2593 2594 if (stcb) { 2595 /* get off the assoc */ 2596 chklist = stcb->asoc.peer_auth_chunks; 2597 /* is there enough space? */ 2598 size = sctp_auth_get_chklist_size(chklist); 2599 if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 2600 error = EINVAL; 2601 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 2602 } else { 2603 /* copy in the chunks */ 2604 (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 2605 } 2606 SCTP_TCB_UNLOCK(stcb); 2607 } else { 2608 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 2609 error = ENOENT; 2610 } 2611 *optsize = sizeof(struct sctp_authchunks) + size; 2612 break; 2613 } 2614 2615 2616 default: 2617 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 2618 error = ENOPROTOOPT; 2619 *optsize = 0; 2620 break; 2621 } /* end switch (sopt->sopt_name) */ 2622 return (error); 2623 } 2624 2625 static int 2626 sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, 2627 void *p) 2628 { 2629 int error, set_opt; 2630 uint32_t *mopt; 2631 struct sctp_tcb *stcb = NULL; 2632 struct sctp_inpcb *inp = NULL; 2633 uint32_t vrf_id; 2634 2635 if (optval == NULL) { 2636 SCTP_PRINTF("optval is NULL\n"); 2637 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2638 return (EINVAL); 2639 } 2640 inp = (struct sctp_inpcb *)so->so_pcb; 2641 if (inp == 0) { 2642 SCTP_PRINTF("inp is NULL?\n"); 2643 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2644 return EINVAL; 2645 } 2646 vrf_id = inp->def_vrf_id; 2647 2648 error = 0; 2649 switch (optname) { 2650 case SCTP_NODELAY: 2651 case SCTP_AUTOCLOSE: 2652 case SCTP_AUTO_ASCONF: 2653 case SCTP_EXPLICIT_EOR: 2654 case SCTP_DISABLE_FRAGMENTS: 2655 case SCTP_USE_EXT_RCVINFO: 2656 case SCTP_I_WANT_MAPPED_V4_ADDR: 2657 /* copy in the option value */ 2658 SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 2659 set_opt = 0; 2660 if (error) 2661 break; 2662 switch (optname) { 2663 case SCTP_DISABLE_FRAGMENTS: 2664 set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT; 2665 break; 2666 case SCTP_AUTO_ASCONF: 2667 /* 2668 * NOTE: we don't really support this flag 2669 */ 2670 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 2671 /* only valid for bound all sockets */ 2672 set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF; 2673 } else { 2674 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2675 return (EINVAL); 2676 } 2677 break; 2678 case SCTP_EXPLICIT_EOR: 2679 set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR; 2680 break; 2681 case SCTP_USE_EXT_RCVINFO: 2682 set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO; 2683 break; 2684 case SCTP_I_WANT_MAPPED_V4_ADDR: 2685 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 2686 set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4; 2687 } else { 2688 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2689 return (EINVAL); 2690 } 2691 break; 2692 case SCTP_NODELAY: 2693 set_opt = SCTP_PCB_FLAGS_NODELAY; 2694 break; 2695 case SCTP_AUTOCLOSE: 2696 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2697 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 2698 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2699 return (EINVAL); 2700 } 2701 set_opt = SCTP_PCB_FLAGS_AUTOCLOSE; 2702 /* 2703 * The value is in ticks. Note this does not effect 2704 * old associations, only new ones. 2705 */ 2706 inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt); 2707 break; 2708 } 2709 SCTP_INP_WLOCK(inp); 2710 if (*mopt != 0) { 2711 sctp_feature_on(inp, set_opt); 2712 } else { 2713 sctp_feature_off(inp, set_opt); 2714 } 2715 SCTP_INP_WUNLOCK(inp); 2716 break; 2717 case SCTP_REUSE_PORT: 2718 { 2719 SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 2720 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 2721 /* Can't set it after we are bound */ 2722 error = EINVAL; 2723 break; 2724 } 2725 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 2726 /* Can't do this for a 1-m socket */ 2727 error = EINVAL; 2728 break; 2729 } 2730 if (optval) 2731 sctp_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 2732 else 2733 sctp_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE); 2734 } 2735 break; 2736 case SCTP_PARTIAL_DELIVERY_POINT: 2737 { 2738 uint32_t *value; 2739 2740 SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize); 2741 if (*value > SCTP_SB_LIMIT_RCV(so)) { 2742 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2743 error = EINVAL; 2744 break; 2745 } 2746 inp->partial_delivery_point = *value; 2747 } 2748 break; 2749 case SCTP_FRAGMENT_INTERLEAVE: 2750 /* not yet until we re-write sctp_recvmsg() */ 2751 { 2752 uint32_t *level; 2753 2754 SCTP_CHECK_AND_CAST(level, optval, uint32_t, optsize); 2755 if (*level == SCTP_FRAG_LEVEL_2) { 2756 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 2757 sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 2758 } else if (*level == SCTP_FRAG_LEVEL_1) { 2759 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 2760 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 2761 } else if (*level == SCTP_FRAG_LEVEL_0) { 2762 sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 2763 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 2764 2765 } else { 2766 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2767 error = EINVAL; 2768 } 2769 } 2770 break; 2771 case SCTP_CMT_ON_OFF: 2772 { 2773 struct sctp_assoc_value *av; 2774 2775 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 2776 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) { 2777 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 2778 if (stcb) { 2779 stcb->asoc.sctp_cmt_on_off = (uint8_t) av->assoc_value; 2780 SCTP_TCB_UNLOCK(stcb); 2781 } else { 2782 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 2783 error = ENOTCONN; 2784 } 2785 } else { 2786 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 2787 error = ENOPROTOOPT; 2788 } 2789 } 2790 break; 2791 /* JRS - Set socket option for pluggable congestion control */ 2792 case SCTP_PLUGGABLE_CC: 2793 { 2794 struct sctp_assoc_value *av; 2795 2796 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 2797 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 2798 if (stcb) { 2799 switch (av->assoc_value) { 2800 /* 2801 * JRS - Standard TCP congestion 2802 * control 2803 */ 2804 case SCTP_CC_RFC2581: 2805 { 2806 stcb->asoc.congestion_control_module = SCTP_CC_RFC2581; 2807 stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_set_initial_cc_param; 2808 stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_cwnd_update_after_sack; 2809 stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_cwnd_update_after_fr; 2810 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_cwnd_update_after_timeout; 2811 stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_cwnd_update_after_ecn_echo; 2812 stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped; 2813 stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output; 2814 stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_cwnd_update_after_fr_timer; 2815 SCTP_TCB_UNLOCK(stcb); 2816 break; 2817 } 2818 /* 2819 * JRS - High Speed TCP congestion 2820 * control (Floyd) 2821 */ 2822 case SCTP_CC_HSTCP: 2823 { 2824 stcb->asoc.congestion_control_module = SCTP_CC_HSTCP; 2825 stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_set_initial_cc_param; 2826 stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_hs_cwnd_update_after_sack; 2827 stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_hs_cwnd_update_after_fr; 2828 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_cwnd_update_after_timeout; 2829 stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_cwnd_update_after_ecn_echo; 2830 stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped; 2831 stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output; 2832 stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_cwnd_update_after_fr_timer; 2833 SCTP_TCB_UNLOCK(stcb); 2834 break; 2835 } 2836 /* JRS - HTCP congestion control */ 2837 case SCTP_CC_HTCP: 2838 { 2839 stcb->asoc.congestion_control_module = SCTP_CC_HTCP; 2840 stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_htcp_set_initial_cc_param; 2841 stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_htcp_cwnd_update_after_sack; 2842 stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_htcp_cwnd_update_after_fr; 2843 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_htcp_cwnd_update_after_timeout; 2844 stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_htcp_cwnd_update_after_ecn_echo; 2845 stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped; 2846 stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output; 2847 stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_htcp_cwnd_update_after_fr_timer; 2848 SCTP_TCB_UNLOCK(stcb); 2849 break; 2850 } 2851 /* 2852 * JRS - All other values are 2853 * invalid 2854 */ 2855 default: 2856 { 2857 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2858 error = EINVAL; 2859 SCTP_TCB_UNLOCK(stcb); 2860 break; 2861 } 2862 } 2863 } else { 2864 switch (av->assoc_value) { 2865 case SCTP_CC_RFC2581: 2866 case SCTP_CC_HSTCP: 2867 case SCTP_CC_HTCP: 2868 inp->sctp_ep.sctp_default_cc_module = av->assoc_value; 2869 break; 2870 default: 2871 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2872 error = EINVAL; 2873 break; 2874 }; 2875 } 2876 } 2877 break; 2878 case SCTP_CLR_STAT_LOG: 2879 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 2880 error = EOPNOTSUPP; 2881 break; 2882 case SCTP_CONTEXT: 2883 { 2884 struct sctp_assoc_value *av; 2885 2886 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 2887 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 2888 2889 if (stcb) { 2890 stcb->asoc.context = av->assoc_value; 2891 SCTP_TCB_UNLOCK(stcb); 2892 } else { 2893 SCTP_INP_WLOCK(inp); 2894 inp->sctp_context = av->assoc_value; 2895 SCTP_INP_WUNLOCK(inp); 2896 } 2897 } 2898 break; 2899 case SCTP_VRF_ID: 2900 { 2901 uint32_t *default_vrfid; 2902 2903 SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, optsize); 2904 if (*default_vrfid > SCTP_MAX_VRF_ID) { 2905 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2906 error = EINVAL; 2907 break; 2908 } 2909 inp->def_vrf_id = *default_vrfid; 2910 break; 2911 } 2912 case SCTP_DEL_VRF_ID: 2913 { 2914 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 2915 error = EOPNOTSUPP; 2916 break; 2917 } 2918 case SCTP_ADD_VRF_ID: 2919 { 2920 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 2921 error = EOPNOTSUPP; 2922 break; 2923 } 2924 case SCTP_DELAYED_SACK: 2925 { 2926 struct sctp_sack_info *sack; 2927 2928 SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize); 2929 SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 2930 if (sack->sack_delay) { 2931 if (sack->sack_delay > SCTP_MAX_SACK_DELAY) 2932 sack->sack_delay = SCTP_MAX_SACK_DELAY; 2933 } 2934 if (stcb) { 2935 if (sack->sack_delay) { 2936 if (MSEC_TO_TICKS(sack->sack_delay) < 1) { 2937 sack->sack_delay = TICKS_TO_MSEC(1); 2938 } 2939 stcb->asoc.delayed_ack = sack->sack_delay; 2940 } 2941 if (sack->sack_freq) { 2942 stcb->asoc.sack_freq = sack->sack_freq; 2943 } 2944 SCTP_TCB_UNLOCK(stcb); 2945 } else { 2946 SCTP_INP_WLOCK(inp); 2947 if (sack->sack_delay) { 2948 if (MSEC_TO_TICKS(sack->sack_delay) < 1) { 2949 sack->sack_delay = TICKS_TO_MSEC(1); 2950 } 2951 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(sack->sack_delay); 2952 } 2953 if (sack->sack_freq) { 2954 inp->sctp_ep.sctp_sack_freq = sack->sack_freq; 2955 } 2956 SCTP_INP_WUNLOCK(inp); 2957 } 2958 break; 2959 } 2960 case SCTP_AUTH_CHUNK: 2961 { 2962 struct sctp_authchunk *sauth; 2963 2964 SCTP_CHECK_AND_CAST(sauth, optval, struct sctp_authchunk, optsize); 2965 2966 SCTP_INP_WLOCK(inp); 2967 if (sctp_auth_add_chunk(sauth->sauth_chunk, inp->sctp_ep.local_auth_chunks)) { 2968 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2969 error = EINVAL; 2970 } 2971 SCTP_INP_WUNLOCK(inp); 2972 break; 2973 } 2974 case SCTP_AUTH_KEY: 2975 { 2976 struct sctp_authkey *sca; 2977 struct sctp_keyhead *shared_keys; 2978 sctp_sharedkey_t *shared_key; 2979 sctp_key_t *key = NULL; 2980 size_t size; 2981 2982 SCTP_CHECK_AND_CAST(sca, optval, struct sctp_authkey, optsize); 2983 SCTP_FIND_STCB(inp, stcb, sca->sca_assoc_id); 2984 size = optsize - sizeof(*sca); 2985 2986 if (stcb) { 2987 /* set it on the assoc */ 2988 shared_keys = &stcb->asoc.shared_keys; 2989 /* clear the cached keys for this key id */ 2990 sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 2991 /* 2992 * create the new shared key and 2993 * insert/replace it 2994 */ 2995 if (size > 0) { 2996 key = sctp_set_key(sca->sca_key, (uint32_t) size); 2997 if (key == NULL) { 2998 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 2999 error = ENOMEM; 3000 SCTP_TCB_UNLOCK(stcb); 3001 break; 3002 } 3003 } 3004 shared_key = sctp_alloc_sharedkey(); 3005 if (shared_key == NULL) { 3006 sctp_free_key(key); 3007 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 3008 error = ENOMEM; 3009 SCTP_TCB_UNLOCK(stcb); 3010 break; 3011 } 3012 shared_key->key = key; 3013 shared_key->keyid = sca->sca_keynumber; 3014 sctp_insert_sharedkey(shared_keys, shared_key); 3015 SCTP_TCB_UNLOCK(stcb); 3016 } else { 3017 /* set it on the endpoint */ 3018 SCTP_INP_WLOCK(inp); 3019 shared_keys = &inp->sctp_ep.shared_keys; 3020 /* 3021 * clear the cached keys on all assocs for 3022 * this key id 3023 */ 3024 sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber); 3025 /* 3026 * create the new shared key and 3027 * insert/replace it 3028 */ 3029 if (size > 0) { 3030 key = sctp_set_key(sca->sca_key, (uint32_t) size); 3031 if (key == NULL) { 3032 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 3033 error = ENOMEM; 3034 SCTP_INP_WUNLOCK(inp); 3035 break; 3036 } 3037 } 3038 shared_key = sctp_alloc_sharedkey(); 3039 if (shared_key == NULL) { 3040 sctp_free_key(key); 3041 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 3042 error = ENOMEM; 3043 SCTP_INP_WUNLOCK(inp); 3044 break; 3045 } 3046 shared_key->key = key; 3047 shared_key->keyid = sca->sca_keynumber; 3048 sctp_insert_sharedkey(shared_keys, shared_key); 3049 SCTP_INP_WUNLOCK(inp); 3050 } 3051 break; 3052 } 3053 case SCTP_HMAC_IDENT: 3054 { 3055 struct sctp_hmacalgo *shmac; 3056 sctp_hmaclist_t *hmaclist; 3057 uint16_t hmacid; 3058 uint32_t i; 3059 3060 size_t found; 3061 3062 SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize); 3063 if (optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) { 3064 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3065 error = EINVAL; 3066 break; 3067 } 3068 hmaclist = sctp_alloc_hmaclist(shmac->shmac_number_of_idents); 3069 if (hmaclist == NULL) { 3070 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 3071 error = ENOMEM; 3072 break; 3073 } 3074 for (i = 0; i < shmac->shmac_number_of_idents; i++) { 3075 hmacid = shmac->shmac_idents[i]; 3076 if (sctp_auth_add_hmacid(hmaclist, hmacid)) { 3077 /* invalid HMACs were found */ ; 3078 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3079 error = EINVAL; 3080 sctp_free_hmaclist(hmaclist); 3081 goto sctp_set_hmac_done; 3082 } 3083 } 3084 found = 0; 3085 for (i = 0; i < hmaclist->num_algo; i++) { 3086 if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) { 3087 /* already in list */ 3088 found = 1; 3089 } 3090 } 3091 if (!found) { 3092 sctp_free_hmaclist(hmaclist); 3093 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3094 error = EINVAL; 3095 break; 3096 } 3097 /* set it on the endpoint */ 3098 SCTP_INP_WLOCK(inp); 3099 if (inp->sctp_ep.local_hmacs) 3100 sctp_free_hmaclist(inp->sctp_ep.local_hmacs); 3101 inp->sctp_ep.local_hmacs = hmaclist; 3102 SCTP_INP_WUNLOCK(inp); 3103 sctp_set_hmac_done: 3104 break; 3105 } 3106 case SCTP_AUTH_ACTIVE_KEY: 3107 { 3108 struct sctp_authkeyid *scact; 3109 3110 SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, optsize); 3111 SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 3112 3113 /* set the active key on the right place */ 3114 if (stcb) { 3115 /* set the active key on the assoc */ 3116 if (sctp_auth_setactivekey(stcb, scact->scact_keynumber)) { 3117 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3118 error = EINVAL; 3119 } 3120 SCTP_TCB_UNLOCK(stcb); 3121 } else { 3122 /* set the active key on the endpoint */ 3123 SCTP_INP_WLOCK(inp); 3124 if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber)) { 3125 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3126 error = EINVAL; 3127 } 3128 SCTP_INP_WUNLOCK(inp); 3129 } 3130 break; 3131 } 3132 case SCTP_AUTH_DELETE_KEY: 3133 { 3134 struct sctp_authkeyid *scdel; 3135 3136 SCTP_CHECK_AND_CAST(scdel, optval, struct sctp_authkeyid, optsize); 3137 SCTP_FIND_STCB(inp, stcb, scdel->scact_assoc_id); 3138 3139 /* delete the key from the right place */ 3140 if (stcb) { 3141 if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber)) { 3142 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3143 error = EINVAL; 3144 } 3145 SCTP_TCB_UNLOCK(stcb); 3146 } else { 3147 SCTP_INP_WLOCK(inp); 3148 if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber)) { 3149 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3150 error = EINVAL; 3151 } 3152 SCTP_INP_WUNLOCK(inp); 3153 } 3154 break; 3155 } 3156 3157 case SCTP_RESET_STREAMS: 3158 { 3159 struct sctp_stream_reset *strrst; 3160 uint8_t send_in = 0, send_tsn = 0, send_out = 0; 3161 int i; 3162 3163 SCTP_CHECK_AND_CAST(strrst, optval, struct sctp_stream_reset, optsize); 3164 SCTP_FIND_STCB(inp, stcb, strrst->strrst_assoc_id); 3165 3166 if (stcb == NULL) { 3167 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 3168 error = ENOENT; 3169 break; 3170 } 3171 if (stcb->asoc.peer_supports_strreset == 0) { 3172 /* 3173 * Peer does not support it, we return 3174 * protocol not supported since this is true 3175 * for this feature and this peer, not the 3176 * socket request in general. 3177 */ 3178 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EPROTONOSUPPORT); 3179 error = EPROTONOSUPPORT; 3180 SCTP_TCB_UNLOCK(stcb); 3181 break; 3182 } 3183 if (stcb->asoc.stream_reset_outstanding) { 3184 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 3185 error = EALREADY; 3186 SCTP_TCB_UNLOCK(stcb); 3187 break; 3188 } 3189 if (strrst->strrst_flags == SCTP_RESET_LOCAL_RECV) { 3190 send_in = 1; 3191 } else if (strrst->strrst_flags == SCTP_RESET_LOCAL_SEND) { 3192 send_out = 1; 3193 } else if (strrst->strrst_flags == SCTP_RESET_BOTH) { 3194 send_in = 1; 3195 send_out = 1; 3196 } else if (strrst->strrst_flags == SCTP_RESET_TSN) { 3197 send_tsn = 1; 3198 } else { 3199 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3200 error = EINVAL; 3201 SCTP_TCB_UNLOCK(stcb); 3202 break; 3203 } 3204 for (i = 0; i < strrst->strrst_num_streams; i++) { 3205 if ((send_in) && 3206 3207 (strrst->strrst_list[i] > stcb->asoc.streamincnt)) { 3208 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3209 error = EINVAL; 3210 goto get_out; 3211 } 3212 if ((send_out) && 3213 (strrst->strrst_list[i] > stcb->asoc.streamoutcnt)) { 3214 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3215 error = EINVAL; 3216 goto get_out; 3217 } 3218 } 3219 if (error) { 3220 get_out: 3221 SCTP_TCB_UNLOCK(stcb); 3222 break; 3223 } 3224 error = sctp_send_str_reset_req(stcb, strrst->strrst_num_streams, 3225 strrst->strrst_list, 3226 send_out, (stcb->asoc.str_reset_seq_in - 3), 3227 send_in, send_tsn); 3228 3229 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 3230 SCTP_TCB_UNLOCK(stcb); 3231 } 3232 break; 3233 3234 case SCTP_CONNECT_X: 3235 if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 3236 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3237 error = EINVAL; 3238 break; 3239 } 3240 error = sctp_do_connect_x(so, inp, optval, optsize, p, 0); 3241 break; 3242 3243 case SCTP_CONNECT_X_DELAYED: 3244 if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 3245 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3246 error = EINVAL; 3247 break; 3248 } 3249 error = sctp_do_connect_x(so, inp, optval, optsize, p, 1); 3250 break; 3251 3252 case SCTP_CONNECT_X_COMPLETE: 3253 { 3254 struct sockaddr *sa; 3255 struct sctp_nets *net; 3256 3257 /* FIXME MT: check correct? */ 3258 SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize); 3259 3260 /* find tcb */ 3261 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3262 SCTP_INP_RLOCK(inp); 3263 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3264 if (stcb) { 3265 SCTP_TCB_LOCK(stcb); 3266 net = sctp_findnet(stcb, sa); 3267 } 3268 SCTP_INP_RUNLOCK(inp); 3269 } else { 3270 /* 3271 * We increment here since 3272 * sctp_findassociation_ep_addr() wil do a 3273 * decrement if it finds the stcb as long as 3274 * the locked tcb (last argument) is NOT a 3275 * TCB.. aka NULL. 3276 */ 3277 SCTP_INP_INCR_REF(inp); 3278 stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL); 3279 if (stcb == NULL) { 3280 SCTP_INP_DECR_REF(inp); 3281 } 3282 } 3283 3284 if (stcb == NULL) { 3285 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 3286 error = ENOENT; 3287 break; 3288 } 3289 if (stcb->asoc.delayed_connection == 1) { 3290 stcb->asoc.delayed_connection = 0; 3291 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 3292 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, 3293 stcb->asoc.primary_destination, 3294 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9); 3295 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 3296 } else { 3297 /* 3298 * already expired or did not use delayed 3299 * connectx 3300 */ 3301 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 3302 error = EALREADY; 3303 } 3304 SCTP_TCB_UNLOCK(stcb); 3305 } 3306 break; 3307 case SCTP_MAX_BURST: 3308 { 3309 uint8_t *burst; 3310 3311 SCTP_CHECK_AND_CAST(burst, optval, uint8_t, optsize); 3312 3313 SCTP_INP_WLOCK(inp); 3314 if (*burst) { 3315 inp->sctp_ep.max_burst = *burst; 3316 } 3317 SCTP_INP_WUNLOCK(inp); 3318 } 3319 break; 3320 case SCTP_MAXSEG: 3321 { 3322 struct sctp_assoc_value *av; 3323 int ovh; 3324 3325 SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 3326 SCTP_FIND_STCB(inp, stcb, av->assoc_id); 3327 3328 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 3329 ovh = SCTP_MED_OVERHEAD; 3330 } else { 3331 ovh = SCTP_MED_V4_OVERHEAD; 3332 } 3333 if (stcb) { 3334 if (av->assoc_value) { 3335 stcb->asoc.sctp_frag_point = (av->assoc_value + ovh); 3336 } else { 3337 stcb->asoc.sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 3338 } 3339 SCTP_TCB_UNLOCK(stcb); 3340 } else { 3341 SCTP_INP_WLOCK(inp); 3342 /* 3343 * FIXME MT: I think this is not in tune 3344 * with the API ID 3345 */ 3346 if (av->assoc_value) { 3347 inp->sctp_frag_point = (av->assoc_value + ovh); 3348 } else { 3349 inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 3350 } 3351 SCTP_INP_WUNLOCK(inp); 3352 } 3353 } 3354 break; 3355 case SCTP_EVENTS: 3356 { 3357 struct sctp_event_subscribe *events; 3358 3359 SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, optsize); 3360 3361 SCTP_INP_WLOCK(inp); 3362 if (events->sctp_data_io_event) { 3363 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 3364 } else { 3365 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 3366 } 3367 3368 if (events->sctp_association_event) { 3369 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 3370 } else { 3371 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 3372 } 3373 3374 if (events->sctp_address_event) { 3375 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 3376 } else { 3377 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 3378 } 3379 3380 if (events->sctp_send_failure_event) { 3381 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 3382 } else { 3383 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 3384 } 3385 3386 if (events->sctp_peer_error_event) { 3387 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR); 3388 } else { 3389 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR); 3390 } 3391 3392 if (events->sctp_shutdown_event) { 3393 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 3394 } else { 3395 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 3396 } 3397 3398 if (events->sctp_partial_delivery_event) { 3399 sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 3400 } else { 3401 sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 3402 } 3403 3404 if (events->sctp_adaptation_layer_event) { 3405 sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 3406 } else { 3407 sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 3408 } 3409 3410 if (events->sctp_authentication_event) { 3411 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT); 3412 } else { 3413 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT); 3414 } 3415 3416 if (events->sctp_stream_reset_events) { 3417 sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 3418 } else { 3419 sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 3420 } 3421 SCTP_INP_WUNLOCK(inp); 3422 } 3423 break; 3424 3425 case SCTP_ADAPTATION_LAYER: 3426 { 3427 struct sctp_setadaptation *adap_bits; 3428 3429 SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize); 3430 SCTP_INP_WLOCK(inp); 3431 inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind; 3432 SCTP_INP_WUNLOCK(inp); 3433 } 3434 break; 3435 #ifdef SCTP_DEBUG 3436 case SCTP_SET_INITIAL_DBG_SEQ: 3437 { 3438 uint32_t *vvv; 3439 3440 SCTP_CHECK_AND_CAST(vvv, optval, uint32_t, optsize); 3441 SCTP_INP_WLOCK(inp); 3442 inp->sctp_ep.initial_sequence_debug = *vvv; 3443 SCTP_INP_WUNLOCK(inp); 3444 } 3445 break; 3446 #endif 3447 case SCTP_DEFAULT_SEND_PARAM: 3448 { 3449 struct sctp_sndrcvinfo *s_info; 3450 3451 SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, optsize); 3452 SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 3453 3454 if (stcb) { 3455 if (s_info->sinfo_stream <= stcb->asoc.streamoutcnt) { 3456 memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send))); 3457 } else { 3458 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3459 error = EINVAL; 3460 } 3461 SCTP_TCB_UNLOCK(stcb); 3462 } else { 3463 SCTP_INP_WLOCK(inp); 3464 memcpy(&inp->def_send, s_info, min(optsize, sizeof(inp->def_send))); 3465 SCTP_INP_WUNLOCK(inp); 3466 } 3467 } 3468 break; 3469 case SCTP_PEER_ADDR_PARAMS: 3470 /* Applys to the specific association */ 3471 { 3472 struct sctp_paddrparams *paddrp; 3473 struct sctp_nets *net; 3474 3475 SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize); 3476 SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 3477 net = NULL; 3478 if (stcb) { 3479 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 3480 } else { 3481 /* 3482 * We increment here since 3483 * sctp_findassociation_ep_addr() wil do a 3484 * decrement if it finds the stcb as long as 3485 * the locked tcb (last argument) is NOT a 3486 * TCB.. aka NULL. 3487 */ 3488 SCTP_INP_INCR_REF(inp); 3489 stcb = sctp_findassociation_ep_addr(&inp, 3490 (struct sockaddr *)&paddrp->spp_address, 3491 &net, NULL, NULL); 3492 if (stcb == NULL) { 3493 SCTP_INP_DECR_REF(inp); 3494 } 3495 } 3496 if (stcb && (net == NULL)) { 3497 struct sockaddr *sa; 3498 3499 sa = (struct sockaddr *)&paddrp->spp_address; 3500 if (sa->sa_family == AF_INET) { 3501 struct sockaddr_in *sin; 3502 3503 sin = (struct sockaddr_in *)sa; 3504 if (sin->sin_addr.s_addr) { 3505 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3506 SCTP_TCB_UNLOCK(stcb); 3507 error = EINVAL; 3508 break; 3509 } 3510 } else if (sa->sa_family == AF_INET6) { 3511 struct sockaddr_in6 *sin6; 3512 3513 sin6 = (struct sockaddr_in6 *)sa; 3514 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 3515 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3516 SCTP_TCB_UNLOCK(stcb); 3517 error = EINVAL; 3518 break; 3519 } 3520 } else { 3521 error = EAFNOSUPPORT; 3522 SCTP_TCB_UNLOCK(stcb); 3523 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3524 break; 3525 } 3526 } 3527 /* sanity checks */ 3528 if ((paddrp->spp_flags & SPP_HB_ENABLE) && (paddrp->spp_flags & SPP_HB_DISABLE)) { 3529 if (stcb) 3530 SCTP_TCB_UNLOCK(stcb); 3531 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3532 return (EINVAL); 3533 } 3534 if ((paddrp->spp_flags & SPP_PMTUD_ENABLE) && (paddrp->spp_flags & SPP_PMTUD_DISABLE)) { 3535 if (stcb) 3536 SCTP_TCB_UNLOCK(stcb); 3537 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3538 return (EINVAL); 3539 } 3540 if (stcb) { 3541 /************************TCB SPECIFIC SET ******************/ 3542 /* 3543 * do we change the timer for HB, we run 3544 * only one? 3545 */ 3546 int ovh = 0; 3547 3548 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 3549 ovh = SCTP_MED_OVERHEAD; 3550 } else { 3551 ovh = SCTP_MED_V4_OVERHEAD; 3552 } 3553 3554 if (paddrp->spp_hbinterval) 3555 stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval; 3556 else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) 3557 stcb->asoc.heart_beat_delay = 0; 3558 3559 /* network sets ? */ 3560 if (net) { 3561 /************************NET SPECIFIC SET ******************/ 3562 if (paddrp->spp_flags & SPP_HB_DEMAND) { 3563 /* on demand HB */ 3564 if (sctp_send_hb(stcb, 1, net) < 0) { 3565 /* asoc destroyed */ 3566 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3567 error = EINVAL; 3568 break; 3569 } 3570 } 3571 if (paddrp->spp_flags & SPP_HB_DISABLE) { 3572 net->dest_state |= SCTP_ADDR_NOHB; 3573 } 3574 if (paddrp->spp_flags & SPP_HB_ENABLE) { 3575 net->dest_state &= ~SCTP_ADDR_NOHB; 3576 } 3577 if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) { 3578 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 3579 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 3580 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10); 3581 } 3582 if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) { 3583 net->mtu = paddrp->spp_pathmtu + ovh; 3584 if (net->mtu < stcb->asoc.smallest_mtu) { 3585 #ifdef SCTP_PRINT_FOR_B_AND_M 3586 SCTP_PRINTF("SCTP_PMTU_DISABLE calls sctp_pathmtu_adjustment:%d\n", 3587 net->mtu); 3588 #endif 3589 sctp_pathmtu_adjustment(inp, stcb, net, net->mtu); 3590 } 3591 } 3592 } 3593 if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 3594 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 3595 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 3596 } 3597 } 3598 if (paddrp->spp_pathmaxrxt) 3599 net->failure_threshold = paddrp->spp_pathmaxrxt; 3600 #ifdef INET 3601 if (paddrp->spp_flags & SPP_IPV4_TOS) { 3602 if (net->ro._l_addr.sin.sin_family == AF_INET) { 3603 net->tos_flowlabel = paddrp->spp_ipv4_tos & 0x000000fc; 3604 } 3605 } 3606 #endif 3607 #ifdef INET6 3608 if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 3609 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) { 3610 net->tos_flowlabel = paddrp->spp_ipv6_flowlabel; 3611 } 3612 } 3613 #endif 3614 } else { 3615 /************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/ 3616 if (paddrp->spp_pathmaxrxt) 3617 stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt; 3618 3619 if (paddrp->spp_flags & SPP_HB_ENABLE) { 3620 /* Turn back on the timer */ 3621 stcb->asoc.hb_is_disabled = 0; 3622 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 3623 } 3624 if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) { 3625 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 3626 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 3627 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 3628 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10); 3629 } 3630 if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) { 3631 net->mtu = paddrp->spp_pathmtu + ovh; 3632 if (net->mtu < stcb->asoc.smallest_mtu) { 3633 #ifdef SCTP_PRINT_FOR_B_AND_M 3634 SCTP_PRINTF("SCTP_PMTU_DISABLE calls sctp_pathmtu_adjustment:%d\n", 3635 net->mtu); 3636 #endif 3637 sctp_pathmtu_adjustment(inp, stcb, net, net->mtu); 3638 } 3639 } 3640 } 3641 } 3642 if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 3643 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 3644 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 3645 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 3646 } 3647 } 3648 } 3649 if (paddrp->spp_flags & SPP_HB_DISABLE) { 3650 int cnt_of_unconf = 0; 3651 struct sctp_nets *lnet; 3652 3653 stcb->asoc.hb_is_disabled = 1; 3654 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 3655 if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) { 3656 cnt_of_unconf++; 3657 } 3658 } 3659 /* 3660 * stop the timer ONLY if we 3661 * have no unconfirmed 3662 * addresses 3663 */ 3664 if (cnt_of_unconf == 0) { 3665 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 3666 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 3667 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11); 3668 } 3669 } 3670 } 3671 if (paddrp->spp_flags & SPP_HB_ENABLE) { 3672 /* start up the timer. */ 3673 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 3674 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 3675 } 3676 } 3677 #ifdef INET 3678 if (paddrp->spp_flags & SPP_IPV4_TOS) 3679 stcb->asoc.default_tos = paddrp->spp_ipv4_tos & 0x000000fc; 3680 #endif 3681 #ifdef INET6 3682 if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) 3683 stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel; 3684 #endif 3685 3686 } 3687 SCTP_TCB_UNLOCK(stcb); 3688 } else { 3689 /************************NO TCB, SET TO default stuff ******************/ 3690 SCTP_INP_WLOCK(inp); 3691 /* 3692 * For the TOS/FLOWLABEL stuff you set it 3693 * with the options on the socket 3694 */ 3695 if (paddrp->spp_pathmaxrxt) { 3696 inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt; 3697 } 3698 if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) 3699 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0; 3700 else if (paddrp->spp_hbinterval) { 3701 if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL) 3702 paddrp->spp_hbinterval = SCTP_MAX_HB_INTERVAL; 3703 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval); 3704 } 3705 if (paddrp->spp_flags & SPP_HB_ENABLE) { 3706 sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 3707 3708 } else if (paddrp->spp_flags & SPP_HB_DISABLE) { 3709 sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 3710 } 3711 SCTP_INP_WUNLOCK(inp); 3712 } 3713 } 3714 break; 3715 case SCTP_RTOINFO: 3716 { 3717 struct sctp_rtoinfo *srto; 3718 uint32_t new_init, new_min, new_max; 3719 3720 SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, optsize); 3721 SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 3722 3723 if (stcb) { 3724 if (srto->srto_initial) 3725 new_init = srto->srto_initial; 3726 else 3727 new_init = stcb->asoc.initial_rto; 3728 if (srto->srto_max) 3729 new_max = srto->srto_max; 3730 else 3731 new_max = stcb->asoc.maxrto; 3732 if (srto->srto_min) 3733 new_min = srto->srto_min; 3734 else 3735 new_min = stcb->asoc.minrto; 3736 if ((new_min <= new_init) && (new_init <= new_max)) { 3737 stcb->asoc.initial_rto = new_init; 3738 stcb->asoc.maxrto = new_max; 3739 stcb->asoc.minrto = new_min; 3740 } else { 3741 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3742 error = EINVAL; 3743 } 3744 SCTP_TCB_UNLOCK(stcb); 3745 } else { 3746 SCTP_INP_WLOCK(inp); 3747 if (srto->srto_initial) 3748 new_init = srto->srto_initial; 3749 else 3750 new_init = inp->sctp_ep.initial_rto; 3751 if (srto->srto_max) 3752 new_max = srto->srto_max; 3753 else 3754 new_max = inp->sctp_ep.sctp_maxrto; 3755 if (srto->srto_min) 3756 new_min = srto->srto_min; 3757 else 3758 new_min = inp->sctp_ep.sctp_minrto; 3759 if ((new_min <= new_init) && (new_init <= new_max)) { 3760 inp->sctp_ep.initial_rto = new_init; 3761 inp->sctp_ep.sctp_maxrto = new_max; 3762 inp->sctp_ep.sctp_minrto = new_min; 3763 } else { 3764 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3765 error = EINVAL; 3766 } 3767 SCTP_INP_WUNLOCK(inp); 3768 } 3769 } 3770 break; 3771 case SCTP_ASSOCINFO: 3772 { 3773 struct sctp_assocparams *sasoc; 3774 3775 SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, optsize); 3776 SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 3777 if (sasoc->sasoc_cookie_life) { 3778 /* boundary check the cookie life */ 3779 if (sasoc->sasoc_cookie_life < 1000) 3780 sasoc->sasoc_cookie_life = 1000; 3781 if (sasoc->sasoc_cookie_life > SCTP_MAX_COOKIE_LIFE) { 3782 sasoc->sasoc_cookie_life = SCTP_MAX_COOKIE_LIFE; 3783 } 3784 } 3785 if (stcb) { 3786 if (sasoc->sasoc_asocmaxrxt) 3787 stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt; 3788 sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets; 3789 sasoc->sasoc_peer_rwnd = 0; 3790 sasoc->sasoc_local_rwnd = 0; 3791 if (sasoc->sasoc_cookie_life) { 3792 stcb->asoc.cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life); 3793 } 3794 SCTP_TCB_UNLOCK(stcb); 3795 } else { 3796 SCTP_INP_WLOCK(inp); 3797 if (sasoc->sasoc_asocmaxrxt) 3798 inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt; 3799 sasoc->sasoc_number_peer_destinations = 0; 3800 sasoc->sasoc_peer_rwnd = 0; 3801 sasoc->sasoc_local_rwnd = 0; 3802 if (sasoc->sasoc_cookie_life) { 3803 inp->sctp_ep.def_cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life); 3804 } 3805 SCTP_INP_WUNLOCK(inp); 3806 } 3807 } 3808 break; 3809 case SCTP_INITMSG: 3810 { 3811 struct sctp_initmsg *sinit; 3812 3813 SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, optsize); 3814 SCTP_INP_WLOCK(inp); 3815 if (sinit->sinit_num_ostreams) 3816 inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams; 3817 3818 if (sinit->sinit_max_instreams) 3819 inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams; 3820 3821 if (sinit->sinit_max_attempts) 3822 inp->sctp_ep.max_init_times = sinit->sinit_max_attempts; 3823 3824 if (sinit->sinit_max_init_timeo) 3825 inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo; 3826 SCTP_INP_WUNLOCK(inp); 3827 } 3828 break; 3829 case SCTP_PRIMARY_ADDR: 3830 { 3831 struct sctp_setprim *spa; 3832 struct sctp_nets *net, *lnet; 3833 3834 SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize); 3835 SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id); 3836 3837 net = NULL; 3838 if (stcb) { 3839 net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr); 3840 } else { 3841 /* 3842 * We increment here since 3843 * sctp_findassociation_ep_addr() wil do a 3844 * decrement if it finds the stcb as long as 3845 * the locked tcb (last argument) is NOT a 3846 * TCB.. aka NULL. 3847 */ 3848 SCTP_INP_INCR_REF(inp); 3849 stcb = sctp_findassociation_ep_addr(&inp, 3850 (struct sockaddr *)&spa->ssp_addr, 3851 &net, NULL, NULL); 3852 if (stcb == NULL) { 3853 SCTP_INP_DECR_REF(inp); 3854 } 3855 } 3856 3857 if ((stcb) && (net)) { 3858 if ((net != stcb->asoc.primary_destination) && 3859 (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) { 3860 /* Ok we need to set it */ 3861 lnet = stcb->asoc.primary_destination; 3862 if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) { 3863 if (net->dest_state & SCTP_ADDR_SWITCH_PRIMARY) { 3864 net->dest_state |= SCTP_ADDR_DOUBLE_SWITCH; 3865 } 3866 net->dest_state |= SCTP_ADDR_SWITCH_PRIMARY; 3867 } 3868 } 3869 } else { 3870 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3871 error = EINVAL; 3872 } 3873 if (stcb) { 3874 SCTP_TCB_UNLOCK(stcb); 3875 } 3876 } 3877 break; 3878 case SCTP_SET_DYNAMIC_PRIMARY: 3879 { 3880 union sctp_sockstore *ss; 3881 3882 error = priv_check(curthread, 3883 PRIV_NETINET_RESERVEDPORT); 3884 if (error) 3885 break; 3886 3887 SCTP_CHECK_AND_CAST(ss, optval, union sctp_sockstore, optsize); 3888 /* SUPER USER CHECK? */ 3889 error = sctp_dynamic_set_primary(&ss->sa, vrf_id); 3890 } 3891 break; 3892 case SCTP_SET_PEER_PRIMARY_ADDR: 3893 { 3894 struct sctp_setpeerprim *sspp; 3895 3896 SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize); 3897 SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id); 3898 if (stcb != NULL) { 3899 struct sctp_ifa *ifa; 3900 3901 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&sspp->sspp_addr, 3902 stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED); 3903 if (ifa == NULL) { 3904 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3905 error = EINVAL; 3906 goto out_of_it; 3907 } 3908 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 3909 /* 3910 * Must validate the ifa found is in 3911 * our ep 3912 */ 3913 struct sctp_laddr *laddr; 3914 int found = 0; 3915 3916 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 3917 if (laddr->ifa == NULL) { 3918 SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n", 3919 __FUNCTION__); 3920 continue; 3921 } 3922 if (laddr->ifa == ifa) { 3923 found = 1; 3924 break; 3925 } 3926 } 3927 if (!found) { 3928 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3929 error = EINVAL; 3930 goto out_of_it; 3931 } 3932 } 3933 if (sctp_set_primary_ip_address_sa(stcb, 3934 (struct sockaddr *)&sspp->sspp_addr) != 0) { 3935 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3936 error = EINVAL; 3937 } 3938 out_of_it: 3939 SCTP_TCB_UNLOCK(stcb); 3940 } else { 3941 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3942 error = EINVAL; 3943 } 3944 3945 } 3946 break; 3947 case SCTP_BINDX_ADD_ADDR: 3948 { 3949 struct sctp_getaddresses *addrs; 3950 size_t sz; 3951 struct thread *td; 3952 int prison = 0; 3953 3954 td = (struct thread *)p; 3955 if (jailed(td->td_ucred)) { 3956 prison = 1; 3957 } 3958 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, 3959 optsize); 3960 if (addrs->addr->sa_family == AF_INET) { 3961 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in); 3962 if (optsize < sz) { 3963 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3964 error = EINVAL; 3965 break; 3966 } 3967 if (prison && prison_ip(td->td_ucred, 0, &(((struct sockaddr_in *)(addrs->addr))->sin_addr.s_addr))) { 3968 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 3969 error = EADDRNOTAVAIL; 3970 } 3971 } else if (addrs->addr->sa_family == AF_INET6) { 3972 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6); 3973 if (optsize < sz) { 3974 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3975 error = EINVAL; 3976 break; 3977 } 3978 /* JAIL XXXX Add else here for V6 */ 3979 } 3980 sctp_bindx_add_address(so, inp, addrs->addr, 3981 addrs->sget_assoc_id, vrf_id, 3982 &error, p); 3983 } 3984 break; 3985 case SCTP_BINDX_REM_ADDR: 3986 { 3987 struct sctp_getaddresses *addrs; 3988 size_t sz; 3989 struct thread *td; 3990 int prison = 0; 3991 3992 td = (struct thread *)p; 3993 if (jailed(td->td_ucred)) { 3994 prison = 1; 3995 } 3996 SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize); 3997 if (addrs->addr->sa_family == AF_INET) { 3998 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in); 3999 if (optsize < sz) { 4000 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4001 error = EINVAL; 4002 break; 4003 } 4004 if (prison && prison_ip(td->td_ucred, 0, &(((struct sockaddr_in *)(addrs->addr))->sin_addr.s_addr))) { 4005 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRNOTAVAIL); 4006 error = EADDRNOTAVAIL; 4007 } 4008 } else if (addrs->addr->sa_family == AF_INET6) { 4009 sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6); 4010 if (optsize < sz) { 4011 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4012 error = EINVAL; 4013 break; 4014 } 4015 /* JAIL XXXX Add else here for V6 */ 4016 } 4017 sctp_bindx_delete_address(so, inp, addrs->addr, 4018 addrs->sget_assoc_id, vrf_id, 4019 &error); 4020 } 4021 break; 4022 default: 4023 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 4024 error = ENOPROTOOPT; 4025 break; 4026 } /* end switch (opt) */ 4027 return (error); 4028 } 4029 4030 int 4031 sctp_ctloutput(struct socket *so, struct sockopt *sopt) 4032 { 4033 void *optval = NULL; 4034 size_t optsize = 0; 4035 struct sctp_inpcb *inp; 4036 void *p; 4037 int error = 0; 4038 4039 inp = (struct sctp_inpcb *)so->so_pcb; 4040 if (inp == 0) { 4041 /* I made the same as TCP since we are not setup? */ 4042 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4043 return (ECONNRESET); 4044 } 4045 if (sopt->sopt_level != IPPROTO_SCTP) { 4046 /* wrong proto level... send back up to IP */ 4047 #ifdef INET6 4048 if (INP_CHECK_SOCKAF(so, AF_INET6)) 4049 error = ip6_ctloutput(so, sopt); 4050 else 4051 #endif /* INET6 */ 4052 error = ip_ctloutput(so, sopt); 4053 return (error); 4054 } 4055 optsize = sopt->sopt_valsize; 4056 if (optsize) { 4057 SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT); 4058 if (optval == NULL) { 4059 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS); 4060 return (ENOBUFS); 4061 } 4062 error = sooptcopyin(sopt, optval, optsize, optsize); 4063 if (error) { 4064 SCTP_FREE(optval, SCTP_M_SOCKOPT); 4065 goto out; 4066 } 4067 } 4068 p = (void *)sopt->sopt_td; 4069 if (sopt->sopt_dir == SOPT_SET) { 4070 error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p); 4071 } else if (sopt->sopt_dir == SOPT_GET) { 4072 error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p); 4073 } else { 4074 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4075 error = EINVAL; 4076 } 4077 if ((error == 0) && (optval != NULL)) { 4078 error = sooptcopyout(sopt, optval, optsize); 4079 SCTP_FREE(optval, SCTP_M_SOCKOPT); 4080 } else if (optval != NULL) { 4081 SCTP_FREE(optval, SCTP_M_SOCKOPT); 4082 } 4083 out: 4084 return (error); 4085 } 4086 4087 4088 static int 4089 sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) 4090 { 4091 int error = 0; 4092 int create_lock_on = 0; 4093 uint32_t vrf_id; 4094 struct sctp_inpcb *inp; 4095 struct sctp_tcb *stcb = NULL; 4096 4097 inp = (struct sctp_inpcb *)so->so_pcb; 4098 if (inp == 0) { 4099 /* I made the same as TCP since we are not setup? */ 4100 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4101 return (ECONNRESET); 4102 } 4103 if (addr == NULL) { 4104 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4105 return EINVAL; 4106 } 4107 if ((addr->sa_family == AF_INET6) && (addr->sa_len != sizeof(struct sockaddr_in6))) { 4108 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4109 return (EINVAL); 4110 } 4111 if ((addr->sa_family == AF_INET) && (addr->sa_len != sizeof(struct sockaddr_in))) { 4112 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4113 return (EINVAL); 4114 } 4115 SCTP_INP_INCR_REF(inp); 4116 SCTP_ASOC_CREATE_LOCK(inp); 4117 create_lock_on = 1; 4118 4119 4120 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 4121 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 4122 /* Should I really unlock ? */ 4123 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 4124 error = EFAULT; 4125 goto out_now; 4126 } 4127 #ifdef INET6 4128 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 4129 (addr->sa_family == AF_INET6)) { 4130 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4131 error = EINVAL; 4132 goto out_now; 4133 } 4134 #endif /* INET6 */ 4135 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 4136 SCTP_PCB_FLAGS_UNBOUND) { 4137 /* Bind a ephemeral port */ 4138 error = sctp_inpcb_bind(so, NULL, NULL, p); 4139 if (error) { 4140 goto out_now; 4141 } 4142 } 4143 /* Now do we connect? */ 4144 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 4145 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 4146 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4147 error = EINVAL; 4148 goto out_now; 4149 } 4150 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 4151 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 4152 /* We are already connected AND the TCP model */ 4153 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 4154 error = EADDRINUSE; 4155 goto out_now; 4156 } 4157 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4158 SCTP_INP_RLOCK(inp); 4159 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4160 SCTP_INP_RUNLOCK(inp); 4161 } else { 4162 /* 4163 * We increment here since sctp_findassociation_ep_addr() 4164 * will do a decrement if it finds the stcb as long as the 4165 * locked tcb (last argument) is NOT a TCB.. aka NULL. 4166 */ 4167 SCTP_INP_INCR_REF(inp); 4168 stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 4169 if (stcb == NULL) { 4170 SCTP_INP_DECR_REF(inp); 4171 } else { 4172 SCTP_TCB_UNLOCK(stcb); 4173 } 4174 } 4175 if (stcb != NULL) { 4176 /* Already have or am bring up an association */ 4177 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 4178 error = EALREADY; 4179 goto out_now; 4180 } 4181 vrf_id = inp->def_vrf_id; 4182 /* We are GOOD to go */ 4183 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id, p); 4184 if (stcb == NULL) { 4185 /* Gak! no memory */ 4186 goto out_now; 4187 } 4188 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 4189 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 4190 /* Set the connected flag so we can queue data */ 4191 soisconnecting(so); 4192 } 4193 SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 4194 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 4195 4196 /* initialize authentication parameters for the assoc */ 4197 sctp_initialize_auth_params(inp, stcb); 4198 4199 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 4200 SCTP_TCB_UNLOCK(stcb); 4201 out_now: 4202 if (create_lock_on) { 4203 SCTP_ASOC_CREATE_UNLOCK(inp); 4204 } 4205 SCTP_INP_DECR_REF(inp); 4206 return error; 4207 } 4208 4209 int 4210 sctp_listen(struct socket *so, int backlog, struct thread *p) 4211 { 4212 /* 4213 * Note this module depends on the protocol processing being called 4214 * AFTER any socket level flags and backlog are applied to the 4215 * socket. The traditional way that the socket flags are applied is 4216 * AFTER protocol processing. We have made a change to the 4217 * sys/kern/uipc_socket.c module to reverse this but this MUST be in 4218 * place if the socket API for SCTP is to work properly. 4219 */ 4220 4221 int error = 0; 4222 struct sctp_inpcb *inp; 4223 4224 inp = (struct sctp_inpcb *)so->so_pcb; 4225 if (inp == 0) { 4226 /* I made the same as TCP since we are not setup? */ 4227 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4228 return (ECONNRESET); 4229 } 4230 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) { 4231 /* See if we have a listener */ 4232 struct sctp_inpcb *tinp; 4233 union sctp_sockstore store, *sp; 4234 4235 sp = &store; 4236 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 4237 /* not bound all */ 4238 struct sctp_laddr *laddr; 4239 4240 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 4241 memcpy(&store, &laddr->ifa->address, sizeof(store)); 4242 sp->sin.sin_port = inp->sctp_lport; 4243 tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); 4244 if (tinp && (tinp != inp) && 4245 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 4246 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 4247 (tinp->sctp_socket->so_qlimit)) { 4248 /* 4249 * we have a listener already and 4250 * its not this inp. 4251 */ 4252 SCTP_INP_DECR_REF(tinp); 4253 return (EADDRINUSE); 4254 } else if (tinp) { 4255 SCTP_INP_DECR_REF(tinp); 4256 } 4257 } 4258 } else { 4259 /* Setup a local addr bound all */ 4260 memset(&store, 0, sizeof(store)); 4261 store.sin.sin_port = inp->sctp_lport; 4262 #ifdef INET6 4263 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 4264 store.sa.sa_family = AF_INET6; 4265 store.sa.sa_len = sizeof(struct sockaddr_in6); 4266 } 4267 #endif 4268 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 4269 store.sa.sa_family = AF_INET; 4270 store.sa.sa_len = sizeof(struct sockaddr_in); 4271 } 4272 tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); 4273 if (tinp && (tinp != inp) && 4274 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 4275 ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 4276 (tinp->sctp_socket->so_qlimit)) { 4277 /* 4278 * we have a listener already and its not 4279 * this inp. 4280 */ 4281 SCTP_INP_DECR_REF(tinp); 4282 return (EADDRINUSE); 4283 } else if (tinp) { 4284 SCTP_INP_DECR_REF(inp); 4285 } 4286 } 4287 } 4288 SCTP_INP_RLOCK(inp); 4289 #ifdef SCTP_LOCK_LOGGING 4290 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) { 4291 sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK); 4292 } 4293 #endif 4294 SOCK_LOCK(so); 4295 error = solisten_proto_check(so); 4296 if (error) { 4297 SOCK_UNLOCK(so); 4298 SCTP_INP_RUNLOCK(inp); 4299 return (error); 4300 } 4301 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) && 4302 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 4303 /* 4304 * The unlucky case - We are in the tcp pool with this guy. 4305 * - Someone else is in the main inp slot. - We must move 4306 * this guy (the listener) to the main slot - We must then 4307 * move the guy that was listener to the TCP Pool. 4308 */ 4309 if (sctp_swap_inpcb_for_listen(inp)) { 4310 goto in_use; 4311 } 4312 } 4313 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 4314 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 4315 /* We are already connected AND the TCP model */ 4316 in_use: 4317 SCTP_INP_RUNLOCK(inp); 4318 SOCK_UNLOCK(so); 4319 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 4320 return (EADDRINUSE); 4321 } 4322 SCTP_INP_RUNLOCK(inp); 4323 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 4324 /* We must do a bind. */ 4325 SOCK_UNLOCK(so); 4326 if ((error = sctp_inpcb_bind(so, NULL, NULL, p))) { 4327 /* bind error, probably perm */ 4328 return (error); 4329 } 4330 SOCK_LOCK(so); 4331 } 4332 /* It appears for 7.0 and on, we must always call this. */ 4333 solisten_proto(so, backlog); 4334 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 4335 /* remove the ACCEPTCONN flag for one-to-many sockets */ 4336 so->so_options &= ~SO_ACCEPTCONN; 4337 } 4338 if (backlog == 0) { 4339 /* turning off listen */ 4340 so->so_options &= ~SO_ACCEPTCONN; 4341 } 4342 SOCK_UNLOCK(so); 4343 return (error); 4344 } 4345 4346 static int sctp_defered_wakeup_cnt = 0; 4347 4348 int 4349 sctp_accept(struct socket *so, struct sockaddr **addr) 4350 { 4351 struct sctp_tcb *stcb; 4352 struct sctp_inpcb *inp; 4353 union sctp_sockstore store; 4354 4355 #ifdef INET6 4356 int error; 4357 4358 #endif 4359 inp = (struct sctp_inpcb *)so->so_pcb; 4360 4361 if (inp == 0) { 4362 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4363 return (ECONNRESET); 4364 } 4365 SCTP_INP_RLOCK(inp); 4366 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 4367 SCTP_INP_RUNLOCK(inp); 4368 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4369 return (EOPNOTSUPP); 4370 } 4371 if (so->so_state & SS_ISDISCONNECTED) { 4372 SCTP_INP_RUNLOCK(inp); 4373 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ECONNABORTED); 4374 return (ECONNABORTED); 4375 } 4376 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4377 if (stcb == NULL) { 4378 SCTP_INP_RUNLOCK(inp); 4379 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4380 return (ECONNRESET); 4381 } 4382 SCTP_TCB_LOCK(stcb); 4383 SCTP_INP_RUNLOCK(inp); 4384 store = stcb->asoc.primary_destination->ro._l_addr; 4385 SCTP_TCB_UNLOCK(stcb); 4386 switch (store.sa.sa_family) { 4387 case AF_INET: 4388 { 4389 struct sockaddr_in *sin; 4390 4391 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 4392 sin->sin_family = AF_INET; 4393 sin->sin_len = sizeof(*sin); 4394 sin->sin_port = ((struct sockaddr_in *)&store)->sin_port; 4395 sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr; 4396 *addr = (struct sockaddr *)sin; 4397 break; 4398 } 4399 #ifdef INET6 4400 case AF_INET6: 4401 { 4402 struct sockaddr_in6 *sin6; 4403 4404 SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); 4405 sin6->sin6_family = AF_INET6; 4406 sin6->sin6_len = sizeof(*sin6); 4407 sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port; 4408 4409 sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr; 4410 if ((error = sa6_recoverscope(sin6)) != 0) { 4411 SCTP_FREE_SONAME(sin6); 4412 return (error); 4413 } 4414 *addr = (struct sockaddr *)sin6; 4415 break; 4416 } 4417 #endif 4418 default: 4419 /* TSNH */ 4420 break; 4421 } 4422 /* Wake any delayed sleep action */ 4423 if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { 4424 SCTP_INP_WLOCK(inp); 4425 inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE; 4426 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) { 4427 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; 4428 SCTP_INP_WUNLOCK(inp); 4429 SOCKBUF_LOCK(&inp->sctp_socket->so_snd); 4430 if (sowriteable(inp->sctp_socket)) { 4431 sowwakeup_locked(inp->sctp_socket); 4432 } else { 4433 SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd); 4434 } 4435 SCTP_INP_WLOCK(inp); 4436 } 4437 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) { 4438 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; 4439 SCTP_INP_WUNLOCK(inp); 4440 SOCKBUF_LOCK(&inp->sctp_socket->so_rcv); 4441 if (soreadable(inp->sctp_socket)) { 4442 sctp_defered_wakeup_cnt++; 4443 sorwakeup_locked(inp->sctp_socket); 4444 } else { 4445 SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv); 4446 } 4447 SCTP_INP_WLOCK(inp); 4448 } 4449 SCTP_INP_WUNLOCK(inp); 4450 } 4451 return (0); 4452 } 4453 4454 int 4455 sctp_ingetaddr(struct socket *so, struct sockaddr **addr) 4456 { 4457 struct sockaddr_in *sin; 4458 uint32_t vrf_id; 4459 struct sctp_inpcb *inp; 4460 struct sctp_ifa *sctp_ifa; 4461 4462 /* 4463 * Do the malloc first in case it blocks. 4464 */ 4465 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 4466 sin->sin_family = AF_INET; 4467 sin->sin_len = sizeof(*sin); 4468 inp = (struct sctp_inpcb *)so->so_pcb; 4469 if (!inp) { 4470 SCTP_FREE_SONAME(sin); 4471 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4472 return ECONNRESET; 4473 } 4474 SCTP_INP_RLOCK(inp); 4475 sin->sin_port = inp->sctp_lport; 4476 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 4477 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4478 struct sctp_tcb *stcb; 4479 struct sockaddr_in *sin_a; 4480 struct sctp_nets *net; 4481 int fnd; 4482 4483 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4484 if (stcb == NULL) { 4485 goto notConn; 4486 } 4487 fnd = 0; 4488 sin_a = NULL; 4489 SCTP_TCB_LOCK(stcb); 4490 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 4491 sin_a = (struct sockaddr_in *)&net->ro._l_addr; 4492 if (sin_a == NULL) 4493 /* this will make coverity happy */ 4494 continue; 4495 4496 if (sin_a->sin_family == AF_INET) { 4497 fnd = 1; 4498 break; 4499 } 4500 } 4501 if ((!fnd) || (sin_a == NULL)) { 4502 /* punt */ 4503 SCTP_TCB_UNLOCK(stcb); 4504 goto notConn; 4505 } 4506 vrf_id = inp->def_vrf_id; 4507 sctp_ifa = sctp_source_address_selection(inp, 4508 stcb, 4509 (sctp_route_t *) & net->ro, 4510 net, 0, vrf_id); 4511 if (sctp_ifa) { 4512 sin->sin_addr = sctp_ifa->address.sin.sin_addr; 4513 sctp_free_ifa(sctp_ifa); 4514 } 4515 SCTP_TCB_UNLOCK(stcb); 4516 } else { 4517 /* For the bound all case you get back 0 */ 4518 notConn: 4519 sin->sin_addr.s_addr = 0; 4520 } 4521 4522 } else { 4523 /* Take the first IPv4 address in the list */ 4524 struct sctp_laddr *laddr; 4525 int fnd = 0; 4526 4527 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 4528 if (laddr->ifa->address.sa.sa_family == AF_INET) { 4529 struct sockaddr_in *sin_a; 4530 4531 sin_a = (struct sockaddr_in *)&laddr->ifa->address.sa; 4532 sin->sin_addr = sin_a->sin_addr; 4533 fnd = 1; 4534 break; 4535 } 4536 } 4537 if (!fnd) { 4538 SCTP_FREE_SONAME(sin); 4539 SCTP_INP_RUNLOCK(inp); 4540 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 4541 return ENOENT; 4542 } 4543 } 4544 SCTP_INP_RUNLOCK(inp); 4545 (*addr) = (struct sockaddr *)sin; 4546 return (0); 4547 } 4548 4549 int 4550 sctp_peeraddr(struct socket *so, struct sockaddr **addr) 4551 { 4552 struct sockaddr_in *sin = (struct sockaddr_in *)*addr; 4553 int fnd; 4554 struct sockaddr_in *sin_a; 4555 struct sctp_inpcb *inp; 4556 struct sctp_tcb *stcb; 4557 struct sctp_nets *net; 4558 4559 /* Do the malloc first in case it blocks. */ 4560 inp = (struct sctp_inpcb *)so->so_pcb; 4561 if ((inp == NULL) || 4562 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) { 4563 /* UDP type and listeners will drop out here */ 4564 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 4565 return (ENOTCONN); 4566 } 4567 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 4568 sin->sin_family = AF_INET; 4569 sin->sin_len = sizeof(*sin); 4570 4571 /* We must recapture incase we blocked */ 4572 inp = (struct sctp_inpcb *)so->so_pcb; 4573 if (!inp) { 4574 SCTP_FREE_SONAME(sin); 4575 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4576 return ECONNRESET; 4577 } 4578 SCTP_INP_RLOCK(inp); 4579 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4580 if (stcb) { 4581 SCTP_TCB_LOCK(stcb); 4582 } 4583 SCTP_INP_RUNLOCK(inp); 4584 if (stcb == NULL) { 4585 SCTP_FREE_SONAME(sin); 4586 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4587 return ECONNRESET; 4588 } 4589 fnd = 0; 4590 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 4591 sin_a = (struct sockaddr_in *)&net->ro._l_addr; 4592 if (sin_a->sin_family == AF_INET) { 4593 fnd = 1; 4594 sin->sin_port = stcb->rport; 4595 sin->sin_addr = sin_a->sin_addr; 4596 break; 4597 } 4598 } 4599 SCTP_TCB_UNLOCK(stcb); 4600 if (!fnd) { 4601 /* No IPv4 address */ 4602 SCTP_FREE_SONAME(sin); 4603 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 4604 return ENOENT; 4605 } 4606 (*addr) = (struct sockaddr *)sin; 4607 return (0); 4608 } 4609 4610 struct pr_usrreqs sctp_usrreqs = { 4611 .pru_abort = sctp_abort, 4612 .pru_accept = sctp_accept, 4613 .pru_attach = sctp_attach, 4614 .pru_bind = sctp_bind, 4615 .pru_connect = sctp_connect, 4616 .pru_control = in_control, 4617 .pru_close = sctp_close, 4618 .pru_detach = sctp_close, 4619 .pru_sopoll = sopoll_generic, 4620 .pru_flush = sctp_flush, 4621 .pru_disconnect = sctp_disconnect, 4622 .pru_listen = sctp_listen, 4623 .pru_peeraddr = sctp_peeraddr, 4624 .pru_send = sctp_sendm, 4625 .pru_shutdown = sctp_shutdown, 4626 .pru_sockaddr = sctp_ingetaddr, 4627 .pru_sosend = sctp_sosend, 4628 .pru_soreceive = sctp_soreceive 4629 }; 4630