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