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