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