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