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