1 /*- 2 * Copyright (c) 2001-2006, Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * b) Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the distribution. 13 * 14 * c) Neither the name of Cisco Systems, Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* $KAME: sctp_usrreq.c,v 1.48 2005/03/07 23:26:08 itojun Exp $ */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 37 #include "opt_ipsec.h" 38 #include "opt_inet6.h" 39 #include "opt_inet.h" 40 41 #include "opt_sctp.h" 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/priv.h> 50 #include <sys/proc.h> 51 #include <sys/protosw.h> 52 #include <sys/socket.h> 53 #include <sys/socketvar.h> 54 #include <sys/sysctl.h> 55 #include <sys/syslog.h> 56 #include <net/if.h> 57 #include <net/if_types.h> 58 #include <net/if_var.h> 59 #include <net/route.h> 60 #include <netinet/in.h> 61 #include <netinet/in_systm.h> 62 #include <netinet/ip.h> 63 #include <netinet/ip6.h> 64 #include <netinet/in_pcb.h> 65 #include <netinet/in_var.h> 66 #include <netinet/ip_var.h> 67 #include <netinet6/ip6_var.h> 68 #include <netinet6/in6_var.h> 69 #include <netinet6/scope6_var.h> 70 #include <netinet/ip_icmp.h> 71 #include <netinet/icmp_var.h> 72 #include <netinet/sctp_os.h> 73 #include <netinet/sctp_pcb.h> 74 #include <netinet/sctp_header.h> 75 #include <netinet/sctp_var.h> 76 #include <netinet/sctp_output.h> 77 #include <netinet/sctp_bsd_addr.h> 78 #include <netinet/sctp_uio.h> 79 #include <netinet/sctp_asconf.h> 80 #include <netinet/sctputil.h> 81 #include <netinet/sctp_indata.h> 82 #include <netinet/sctp_asconf.h> 83 #include <netinet/sctp_timer.h> 84 #include <netinet/sctp_auth.h> 85 86 #ifdef IPSEC 87 #include <netinet6/ipsec.h> 88 #include <netkey/key.h> 89 #endif /* IPSEC */ 90 91 92 93 94 #ifndef in6pcb 95 #define in6pcb inpcb 96 #endif 97 #ifndef sotoin6pcb 98 #define sotoin6pcb sotoinpcb 99 #endif 100 101 102 103 /* 104 * sysctl tunable variables 105 */ 106 int sctp_sendspace = (128 * 1024); 107 int sctp_recvspace = 128 * (1024 + 108 #ifdef INET6 109 sizeof(struct sockaddr_in6) 110 #else 111 sizeof(struct sockaddr_in) 112 #endif 113 ); 114 int sctp_mbuf_threshold_count = SCTP_DEFAULT_MBUFS_IN_CHAIN; 115 int sctp_auto_asconf = SCTP_DEFAULT_AUTO_ASCONF; 116 int sctp_ecn_enable = 1; 117 int sctp_ecn_nonce = 0; 118 int sctp_strict_sacks = 0; 119 int sctp_no_csum_on_loopback = 1; 120 int sctp_strict_init = 1; 121 int sctp_abort_if_one_2_one_hits_limit = 0; 122 int sctp_strict_data_order = 0; 123 124 int sctp_peer_chunk_oh = sizeof(struct mbuf); 125 int sctp_max_burst_default = SCTP_DEF_MAX_BURST; 126 int sctp_use_cwnd_based_maxburst = 1; 127 int sctp_do_drain = 1; 128 int sctp_warm_the_crc32_table = 0; 129 130 unsigned int sctp_max_chunks_on_queue = SCTP_ASOC_MAX_CHUNKS_ON_QUEUE; 131 unsigned int sctp_delayed_sack_time_default = SCTP_RECV_MSEC; 132 unsigned int sctp_heartbeat_interval_default = SCTP_HB_DEFAULT_MSEC; 133 unsigned int sctp_pmtu_raise_time_default = SCTP_DEF_PMTU_RAISE_SEC; 134 unsigned int sctp_shutdown_guard_time_default = SCTP_DEF_MAX_SHUTDOWN_SEC; 135 unsigned int sctp_secret_lifetime_default = SCTP_DEFAULT_SECRET_LIFE_SEC; 136 unsigned int sctp_rto_max_default = SCTP_RTO_UPPER_BOUND; 137 unsigned int sctp_rto_min_default = SCTP_RTO_LOWER_BOUND; 138 unsigned int sctp_rto_initial_default = SCTP_RTO_INITIAL; 139 unsigned int sctp_init_rto_max_default = SCTP_RTO_UPPER_BOUND; 140 unsigned int sctp_valid_cookie_life_default = SCTP_DEFAULT_COOKIE_LIFE; 141 unsigned int sctp_init_rtx_max_default = SCTP_DEF_MAX_INIT; 142 unsigned int sctp_assoc_rtx_max_default = SCTP_DEF_MAX_SEND; 143 unsigned int sctp_path_rtx_max_default = SCTP_DEF_MAX_PATH_RTX; 144 unsigned int sctp_nr_outgoing_streams_default = SCTP_OSTREAM_INITIAL; 145 unsigned int sctp_add_more_threshold = SCTP_DEFAULT_ADD_MORE; 146 147 uint32_t sctp_asoc_free_resc_limit = SCTP_DEF_ASOC_RESC_LIMIT; 148 uint32_t sctp_system_free_resc_limit = SCTP_DEF_SYSTEM_RESC_LIMIT; 149 150 int sctp_min_split_point = SCTP_DEFAULT_SPLIT_POINT_MIN; 151 int sctp_pcbtblsize = SCTP_PCBHASHSIZE; 152 int sctp_hashtblsize = SCTP_TCBHASHSIZE; 153 int sctp_chunkscale = SCTP_CHUNKQUEUE_SCALE; 154 155 unsigned int sctp_cmt_on_off = 0; 156 unsigned int sctp_cmt_sockopt_on_off = 0; 157 unsigned int sctp_cmt_use_dac = 0; 158 unsigned int sctp_cmt_sockopt_use_dac = 0; 159 160 int sctp_L2_abc_variable = 1; 161 unsigned int sctp_early_fr = 0; 162 unsigned int sctp_early_fr_msec = SCTP_MINFR_MSEC_TIMER; 163 unsigned int sctp_use_rttvar_cc = 0; 164 int sctp_says_check_for_deadlock = 0; 165 unsigned int sctp_asconf_auth_nochk = 0; 166 unsigned int sctp_nat_friendly = 1; 167 unsigned int sctp_auth_disable = 0; 168 unsigned int sctp_auth_random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT; 169 unsigned int sctp_auth_hmac_id_default = SCTP_AUTH_HMAC_ID_SHA1; 170 struct sctpstat sctpstat; 171 172 #ifdef SCTP_DEBUG 173 extern uint32_t sctp_debug_on; 174 175 #endif /* SCTP_DEBUG */ 176 177 178 void 179 sctp_init(void) 180 { 181 /* Init the SCTP pcb in sctp_pcb.c */ 182 u_long sb_max_adj; 183 184 sctp_pcb_init(); 185 186 if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE) 187 sctp_max_chunks_on_queue = (nmbclusters / 8); 188 /* 189 * Allow a user to take no more than 1/2 the number of clusters or 190 * the SB_MAX whichever is smaller for the send window. 191 */ 192 sb_max_adj = (u_long)((u_quad_t) (SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES)); 193 sctp_sendspace = min((min(SB_MAX, sb_max_adj)), 194 ((nmbclusters / 2) * SCTP_DEFAULT_MAXSEGMENT)); 195 /* 196 * Now for the recv window, should we take the same amount? or 197 * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For 198 * now I will just copy. 199 */ 200 sctp_recvspace = sctp_sendspace; 201 202 203 } 204 205 206 #ifdef INET6 207 void 208 ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip) 209 { 210 bzero(ip6, sizeof(*ip6)); 211 212 ip6->ip6_vfc = IPV6_VERSION; 213 ip6->ip6_plen = ip->ip_len; 214 ip6->ip6_nxt = ip->ip_p; 215 ip6->ip6_hlim = ip->ip_ttl; 216 ip6->ip6_src.s6_addr32[2] = ip6->ip6_dst.s6_addr32[2] = 217 IPV6_ADDR_INT32_SMP; 218 ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr; 219 ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr; 220 } 221 222 #endif /* INET6 */ 223 224 225 static void 226 sctp_pathmtu_adustment(struct sctp_inpcb *inp, 227 struct sctp_tcb *stcb, 228 struct sctp_nets *net, 229 uint16_t nxtsz) 230 { 231 struct sctp_tmit_chunk *chk; 232 233 /* Adjust that too */ 234 stcb->asoc.smallest_mtu = nxtsz; 235 /* now off to subtract IP_DF flag if needed */ 236 237 TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) { 238 if ((chk->send_size + IP_HDR_SIZE) > nxtsz) { 239 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 240 } 241 } 242 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 243 if ((chk->send_size + IP_HDR_SIZE) > nxtsz) { 244 /* 245 * For this guy we also mark for immediate resend 246 * since we sent to big of chunk 247 */ 248 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 249 if (chk->sent != SCTP_DATAGRAM_RESEND) { 250 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 251 } 252 chk->sent = SCTP_DATAGRAM_RESEND; 253 chk->rec.data.doing_fast_retransmit = 0; 254 255 /* Clear any time so NO RTT is being done */ 256 chk->do_rtt = 0; 257 if (stcb->asoc.total_flight >= chk->book_size) 258 stcb->asoc.total_flight -= chk->book_size; 259 else 260 stcb->asoc.total_flight = 0; 261 if (stcb->asoc.total_flight_count > 0) 262 stcb->asoc.total_flight_count--; 263 if (net->flight_size >= chk->book_size) 264 net->flight_size -= chk->book_size; 265 else 266 net->flight_size = 0; 267 } 268 } 269 } 270 271 static void 272 sctp_notify_mbuf(struct sctp_inpcb *inp, 273 struct sctp_tcb *stcb, 274 struct sctp_nets *net, 275 struct ip *ip, 276 struct sctphdr *sh) 277 { 278 struct icmp *icmph; 279 int totsz, tmr_stopped = 0; 280 uint16_t nxtsz; 281 282 /* protection */ 283 if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 284 (ip == NULL) || (sh == NULL)) { 285 if (stcb != NULL) 286 SCTP_TCB_UNLOCK(stcb); 287 return; 288 } 289 /* First job is to verify the vtag matches what I would send */ 290 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 291 SCTP_TCB_UNLOCK(stcb); 292 return; 293 } 294 icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) - 295 sizeof(struct ip))); 296 if (icmph->icmp_type != ICMP_UNREACH) { 297 /* We only care about unreachable */ 298 SCTP_TCB_UNLOCK(stcb); 299 return; 300 } 301 if (icmph->icmp_code != ICMP_UNREACH_NEEDFRAG) { 302 /* not a unreachable message due to frag. */ 303 SCTP_TCB_UNLOCK(stcb); 304 return; 305 } 306 totsz = ip->ip_len; 307 308 nxtsz = ntohs(icmph->icmp_seq); 309 if (nxtsz == 0) { 310 /* 311 * old type router that does not tell us what the next size 312 * mtu is. Rats we will have to guess (in a educated fashion 313 * of course) 314 */ 315 nxtsz = find_next_best_mtu(totsz); 316 } 317 /* Stop any PMTU timer */ 318 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 319 tmr_stopped = 1; 320 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 321 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1); 322 } 323 /* Adjust destination size limit */ 324 if (net->mtu > nxtsz) { 325 net->mtu = nxtsz; 326 } 327 /* now what about the ep? */ 328 if (stcb->asoc.smallest_mtu > nxtsz) { 329 sctp_pathmtu_adustment(inp, stcb, net, nxtsz); 330 } 331 if (tmr_stopped) 332 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 333 334 SCTP_TCB_UNLOCK(stcb); 335 } 336 337 338 void 339 sctp_notify(struct sctp_inpcb *inp, 340 int errno, 341 struct sctphdr *sh, 342 struct sockaddr *to, 343 struct sctp_tcb *stcb, 344 struct sctp_nets *net) 345 { 346 /* protection */ 347 if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 348 (sh == NULL) || (to == NULL)) { 349 return; 350 } 351 /* First job is to verify the vtag matches what I would send */ 352 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 353 return; 354 } 355 /* FIX ME FIX ME PROTOPT i.e. no SCTP should ALWAYS be an ABORT */ 356 357 if ((errno == EHOSTUNREACH) || /* Host is not reachable */ 358 (errno == EHOSTDOWN) || /* Host is down */ 359 (errno == ECONNREFUSED) || /* Host refused the connection, (not 360 * an abort?) */ 361 (errno == ENOPROTOOPT) /* SCTP is not present on host */ 362 ) { 363 /* 364 * Hmm reachablity problems we must examine closely. If its 365 * not reachable, we may have lost a network. Or if there is 366 * NO protocol at the other end named SCTP. well we consider 367 * it a OOTB abort. 368 */ 369 if ((errno == EHOSTUNREACH) || (errno == EHOSTDOWN)) { 370 if (net->dest_state & SCTP_ADDR_REACHABLE) { 371 /* Ok that destination is NOT reachable */ 372 net->dest_state &= ~SCTP_ADDR_REACHABLE; 373 net->dest_state |= SCTP_ADDR_NOT_REACHABLE; 374 net->error_count = net->failure_threshold + 1; 375 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 376 stcb, SCTP_FAILED_THRESHOLD, 377 (void *)net); 378 } 379 if (stcb) 380 SCTP_TCB_UNLOCK(stcb); 381 } else { 382 /* 383 * Here the peer is either playing tricks on us, 384 * including an address that belongs to someone who 385 * does not support SCTP OR was a userland 386 * implementation that shutdown and now is dead. In 387 * either case treat it like a OOTB abort with no 388 * TCB 389 */ 390 sctp_abort_notification(stcb, SCTP_PEER_FAULTY); 391 sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2); 392 /* no need to unlock here, since the TCB is gone */ 393 } 394 } else { 395 /* Send all others to the app */ 396 if (stcb) 397 SCTP_TCB_UNLOCK(stcb); 398 399 400 if (inp->sctp_socket) { 401 #ifdef SCTP_LOCK_LOGGING 402 sctp_log_lock(inp, stcb, SCTP_LOG_LOCK_SOCK); 403 #endif 404 SOCK_LOCK(inp->sctp_socket); 405 inp->sctp_socket->so_error = errno; 406 sctp_sowwakeup(inp, inp->sctp_socket); 407 SOCK_UNLOCK(inp->sctp_socket); 408 } 409 } 410 } 411 412 void 413 sctp_ctlinput(cmd, sa, vip) 414 int cmd; 415 struct sockaddr *sa; 416 void *vip; 417 { 418 struct ip *ip = vip; 419 struct sctphdr *sh; 420 int s; 421 422 423 if (sa->sa_family != AF_INET || 424 ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) { 425 return; 426 } 427 if (PRC_IS_REDIRECT(cmd)) { 428 ip = 0; 429 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) { 430 return; 431 } 432 if (ip) { 433 struct sctp_inpcb *inp = NULL; 434 struct sctp_tcb *stcb = NULL; 435 struct sctp_nets *net = NULL; 436 struct sockaddr_in to, from; 437 438 sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 439 bzero(&to, sizeof(to)); 440 bzero(&from, 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. Thus we reverse 451 * the to and the from in the lookup. 452 */ 453 s = splnet(); 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 461 if (cmd == PRC_HOSTDEAD) { 462 cm = EHOSTUNREACH; 463 } else { 464 cm = inetctlerrmap[cmd]; 465 } 466 sctp_notify(inp, cm, sh, 467 (struct sockaddr *)&to, stcb, 468 net); 469 } else { 470 /* handle possible ICMP size messages */ 471 sctp_notify_mbuf(inp, stcb, net, ip, sh); 472 } 473 } else { 474 if ((stcb == NULL) && (inp != NULL)) { 475 /* reduce ref-count */ 476 SCTP_INP_WLOCK(inp); 477 SCTP_INP_DECR_REF(inp); 478 SCTP_INP_WUNLOCK(inp); 479 } 480 } 481 splx(s); 482 } 483 return; 484 } 485 486 static int 487 sctp_getcred(SYSCTL_HANDLER_ARGS) 488 { 489 struct xucred xuc; 490 struct sockaddr_in addrs[2]; 491 struct sctp_inpcb *inp; 492 struct sctp_nets *net; 493 struct sctp_tcb *stcb; 494 int error; 495 496 /* 497 * XXXRW: Other instances of getcred use SUSER_ALLOWJAIL, as socket 498 * visibility is scoped using cr_canseesocket(), which it is not 499 * here. 500 */ 501 error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED, 0); 502 if (error) 503 return (error); 504 505 error = SYSCTL_IN(req, addrs, sizeof(addrs)); 506 if (error) 507 return (error); 508 509 stcb = sctp_findassociation_addr_sa(sintosa(&addrs[0]), 510 sintosa(&addrs[1]), 511 &inp, &net, 1); 512 if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) { 513 if ((inp != NULL) && (stcb == NULL)) { 514 /* reduce ref-count */ 515 SCTP_INP_WLOCK(inp); 516 SCTP_INP_DECR_REF(inp); 517 goto cred_can_cont; 518 } 519 error = ENOENT; 520 goto out; 521 } 522 SCTP_TCB_UNLOCK(stcb); 523 /* 524 * We use the write lock here, only since in the error leg we need 525 * it. If we used RLOCK, then we would have to 526 * wlock/decr/unlock/rlock. Which in theory could create a hole. 527 * Better to use higher wlock. 528 */ 529 SCTP_INP_WLOCK(inp); 530 cred_can_cont: 531 error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket); 532 if (error) { 533 SCTP_INP_WUNLOCK(inp); 534 goto out; 535 } 536 cru2x(inp->sctp_socket->so_cred, &xuc); 537 SCTP_INP_WUNLOCK(inp); 538 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 539 out: 540 return (error); 541 } 542 543 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW, 544 0, 0, sctp_getcred, "S,ucred", "Get the ucred of a SCTP connection"); 545 546 static int 547 sctp_assoclist(SYSCTL_HANDLER_ARGS) 548 { 549 unsigned int number_of_endpoints; 550 unsigned int number_of_local_addresses; 551 unsigned int number_of_associations; 552 unsigned int number_of_remote_addresses; 553 unsigned int n; 554 int error; 555 struct sctp_inpcb *inp; 556 struct sctp_tcb *stcb; 557 struct sctp_nets *net; 558 struct sctp_laddr *laddr; 559 struct xsctp_inpcb xinpcb; 560 struct xsctp_tcb xstcb; 561 562 /* struct xsctp_laddr xladdr; */ 563 struct xsctp_raddr xraddr; 564 565 number_of_endpoints = 0; 566 number_of_local_addresses = 0; 567 number_of_associations = 0; 568 number_of_remote_addresses = 0; 569 570 SCTP_INP_INFO_RLOCK(); 571 if (req->oldptr == USER_ADDR_NULL) { 572 LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) { 573 SCTP_INP_RLOCK(inp); 574 number_of_endpoints++; 575 /* FIXME MT */ 576 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 577 number_of_local_addresses++; 578 } 579 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 580 number_of_associations++; 581 /* FIXME MT */ 582 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) { 583 number_of_local_addresses++; 584 } 585 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 586 number_of_remote_addresses++; 587 } 588 } 589 SCTP_INP_RUNLOCK(inp); 590 } 591 SCTP_INP_INFO_RUNLOCK(); 592 n = (number_of_endpoints + 1) * sizeof(struct xsctp_inpcb) + 593 number_of_local_addresses * sizeof(struct xsctp_laddr) + 594 number_of_associations * sizeof(struct xsctp_tcb) + 595 number_of_remote_addresses * sizeof(struct xsctp_raddr); 596 #ifdef SCTP_DEBUG 597 printf("inps = %u, stcbs = %u, laddrs = %u, raddrs = %u\n", 598 number_of_endpoints, number_of_associations, 599 number_of_local_addresses, number_of_remote_addresses); 600 #endif 601 /* request some more memory than needed */ 602 req->oldidx = (n + n / 8); 603 return 0; 604 } 605 if (req->newptr != USER_ADDR_NULL) { 606 SCTP_INP_INFO_RUNLOCK(); 607 return EPERM; 608 } 609 LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) { 610 SCTP_INP_RLOCK(inp); 611 number_of_local_addresses = 0; 612 number_of_associations = 0; 613 /* 614 * LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) 615 * { number_of_local_addresses++; } 616 */ 617 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 618 number_of_associations++; 619 } 620 xinpcb.last = 0; 621 xinpcb.local_port = ntohs(inp->sctp_lport); 622 xinpcb.number_local_addresses = number_of_local_addresses; 623 xinpcb.number_associations = number_of_associations; 624 xinpcb.flags = inp->sctp_flags; 625 xinpcb.features = inp->sctp_features; 626 xinpcb.total_sends = inp->total_sends; 627 xinpcb.total_recvs = inp->total_recvs; 628 xinpcb.total_nospaces = inp->total_nospaces; 629 SCTP_INP_INCR_REF(inp); 630 SCTP_INP_RUNLOCK(inp); 631 SCTP_INP_INFO_RUNLOCK(); 632 error = SYSCTL_OUT(req, &xinpcb, sizeof(struct xsctp_inpcb)); 633 if (error) { 634 return error; 635 } 636 SCTP_INP_INFO_RLOCK(); 637 SCTP_INP_RLOCK(inp); 638 /* FIXME MT */ 639 /* 640 * LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) 641 * { error = SYSCTL_OUT(req, &xladdr, sizeof(struct 642 * xsctp_laddr)); if (error) { #if 643 * defined(SCTP_APPLE_FINE_GRAINED_LOCKING) 644 * socket_unlock(inp->ip_inp.inp.inp_socket, 1); 645 * lck_rw_unlock_shared(sctppcbinfo.ipi_ep_mtx); #endif 646 * SCTP_INP_RUNLOCK(inp); SCTP_INP_INFO_RUNLOCK(); return 647 * error; } } 648 */ 649 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 650 SCTP_TCB_LOCK(stcb); 651 atomic_add_int(&stcb->asoc.refcnt, 1); 652 SCTP_TCB_UNLOCK(stcb); 653 number_of_local_addresses = 0; 654 number_of_remote_addresses = 0; 655 /* FIXME MT */ 656 /* 657 * LIST_FOREACH(laddr, 658 * &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) 659 * { number_of_local_addresses++; } 660 */ 661 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 662 number_of_remote_addresses++; 663 } 664 xstcb.remote_port = ntohs(stcb->rport); 665 xstcb.number_local_addresses = number_of_local_addresses; 666 xstcb.number_remote_addresses = number_of_remote_addresses; 667 xstcb.number_incomming_streams = 0; 668 xstcb.number_outgoing_streams = 0; 669 xstcb.state = stcb->asoc.state; 670 xstcb.total_sends = stcb->total_sends; 671 xstcb.total_recvs = stcb->total_recvs; 672 xstcb.local_tag = stcb->asoc.my_vtag; 673 xstcb.remote_tag = stcb->asoc.peer_vtag; 674 xstcb.initial_tsn = stcb->asoc.init_seq_number; 675 xstcb.highest_tsn = stcb->asoc.sending_seq - 1; 676 xstcb.cumulative_tsn = stcb->asoc.last_acked_seq; 677 xstcb.cumulative_tsn_ack = stcb->asoc.cumulative_tsn; 678 SCTP_INP_RUNLOCK(inp); 679 SCTP_INP_INFO_RUNLOCK(); 680 error = SYSCTL_OUT(req, &xstcb, sizeof(struct xsctp_tcb)); 681 if (error) { 682 atomic_add_int(&stcb->asoc.refcnt, -1); 683 return error; 684 } 685 /* FIXME MT */ 686 /* 687 * LIST_FOREACH(laddr, 688 * &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) 689 * { error = SYSCTL_OUT(req, &xladdr, sizeof(struct 690 * xsctp_laddr)); if (error) { #if 691 * defined(SCTP_APPLE_FINE_GRAINED_LOCKING) 692 * socket_unlock(inp->ip_inp.inp.inp_socket, 1); 693 * lck_rw_unlock_shared(sctppcbinfo.ipi_ep_mtx); 694 * #endif SCTP_INP_RUNLOCK(inp); 695 * SCTP_INP_INFO_RUNLOCK(); return error; } 696 * */ 697 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 698 xraddr.state = net->dest_state; 699 xraddr.address = net->ro._l_addr; 700 error = SYSCTL_OUT(req, &xraddr, sizeof(struct xsctp_raddr)); 701 if (error) { 702 atomic_add_int(&stcb->asoc.refcnt, -1); 703 return error; 704 } 705 } 706 atomic_add_int(&stcb->asoc.refcnt, -1); 707 SCTP_INP_INFO_RLOCK(); 708 SCTP_INP_RLOCK(inp); 709 } 710 SCTP_INP_DECR_REF(inp); 711 SCTP_INP_RUNLOCK(inp); 712 } 713 SCTP_INP_INFO_RUNLOCK(); 714 715 xinpcb.last = 1; 716 xinpcb.local_port = 0; 717 xinpcb.number_local_addresses = 0; 718 xinpcb.number_associations = 0; 719 xinpcb.flags = 0; 720 xinpcb.features = 0; 721 error = SYSCTL_OUT(req, &xinpcb, sizeof(struct xsctp_inpcb)); 722 return error; 723 } 724 725 /* 726 * sysctl definitions 727 */ 728 729 SYSCTL_INT(_net_inet_sctp, OID_AUTO, sendspace, CTLFLAG_RW, 730 &sctp_sendspace, 0, "Maximum outgoing SCTP buffer size"); 731 732 SYSCTL_INT(_net_inet_sctp, OID_AUTO, recvspace, CTLFLAG_RW, 733 &sctp_recvspace, 0, "Maximum incoming SCTP buffer size"); 734 735 SYSCTL_INT(_net_inet_sctp, OID_AUTO, auto_asconf, CTLFLAG_RW, 736 &sctp_auto_asconf, 0, "Enable SCTP Auto-ASCONF"); 737 738 SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_enable, CTLFLAG_RW, 739 &sctp_ecn_enable, 0, "Enable SCTP ECN"); 740 741 SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_nonce, CTLFLAG_RW, 742 &sctp_ecn_nonce, 0, "Enable SCTP ECN Nonce"); 743 744 SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_sacks, CTLFLAG_RW, 745 &sctp_strict_sacks, 0, "Enable SCTP Strict SACK checking"); 746 747 SYSCTL_INT(_net_inet_sctp, OID_AUTO, loopback_nocsum, CTLFLAG_RW, 748 &sctp_no_csum_on_loopback, 0, 749 "Enable NO Csum on packets sent on loopback"); 750 751 SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_init, CTLFLAG_RW, 752 &sctp_strict_init, 0, 753 "Enable strict INIT/INIT-ACK singleton enforcement"); 754 755 SYSCTL_INT(_net_inet_sctp, OID_AUTO, peer_chkoh, CTLFLAG_RW, 756 &sctp_peer_chunk_oh, 0, 757 "Amount to debit peers rwnd per chunk sent"); 758 759 SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxburst, CTLFLAG_RW, 760 &sctp_max_burst_default, 0, 761 "Default max burst for sctp endpoints"); 762 763 SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxchunks, CTLFLAG_RW, 764 &sctp_max_chunks_on_queue, 0, 765 "Default max chunks on queue per asoc"); 766 767 SYSCTL_INT(_net_inet_sctp, OID_AUTO, tcbhashsize, CTLFLAG_RW, 768 &sctp_hashtblsize, 0, 769 "Tuneable for Hash table sizes"); 770 771 SYSCTL_INT(_net_inet_sctp, OID_AUTO, min_split_point, CTLFLAG_RW, 772 &sctp_min_split_point, 0, 773 "Minimum size when splitting a chunk"); 774 775 SYSCTL_INT(_net_inet_sctp, OID_AUTO, pcbhashsize, CTLFLAG_RW, 776 &sctp_pcbtblsize, 0, 777 "Tuneable for PCB Hash table sizes"); 778 779 SYSCTL_INT(_net_inet_sctp, OID_AUTO, sys_resource, CTLFLAG_RW, 780 &sctp_system_free_resc_limit, 0, 781 "Max number of cached resources in the system"); 782 783 SYSCTL_INT(_net_inet_sctp, OID_AUTO, asoc_resource, CTLFLAG_RW, 784 &sctp_asoc_free_resc_limit, 0, 785 "Max number of cached resources in an asoc"); 786 787 SYSCTL_INT(_net_inet_sctp, OID_AUTO, chunkscale, CTLFLAG_RW, 788 &sctp_chunkscale, 0, 789 "Tuneable for Scaling of number of chunks and messages"); 790 791 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, delayed_sack_time, CTLFLAG_RW, 792 &sctp_delayed_sack_time_default, 0, 793 "Default delayed SACK timer in msec"); 794 795 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, heartbeat_interval, CTLFLAG_RW, 796 &sctp_heartbeat_interval_default, 0, 797 "Default heartbeat interval in msec"); 798 799 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, pmtu_raise_time, CTLFLAG_RW, 800 &sctp_pmtu_raise_time_default, 0, 801 "Default PMTU raise timer in sec"); 802 803 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, shutdown_guard_time, CTLFLAG_RW, 804 &sctp_shutdown_guard_time_default, 0, 805 "Default shutdown guard timer in sec"); 806 807 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, secret_lifetime, CTLFLAG_RW, 808 &sctp_secret_lifetime_default, 0, 809 "Default secret lifetime in sec"); 810 811 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_max, CTLFLAG_RW, 812 &sctp_rto_max_default, 0, 813 "Default maximum retransmission timeout in msec"); 814 815 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_min, CTLFLAG_RW, 816 &sctp_rto_min_default, 0, 817 "Default minimum retransmission timeout in msec"); 818 819 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_initial, CTLFLAG_RW, 820 &sctp_rto_initial_default, 0, 821 "Default initial retransmission timeout in msec"); 822 823 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, init_rto_max, CTLFLAG_RW, 824 &sctp_init_rto_max_default, 0, 825 "Default maximum retransmission timeout during association setup in msec"); 826 827 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, valid_cookie_life, CTLFLAG_RW, 828 &sctp_valid_cookie_life_default, 0, 829 "Default cookie lifetime in sec"); 830 831 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, init_rtx_max, CTLFLAG_RW, 832 &sctp_init_rtx_max_default, 0, 833 "Default maximum number of retransmission for INIT chunks"); 834 835 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, assoc_rtx_max, CTLFLAG_RW, 836 &sctp_assoc_rtx_max_default, 0, 837 "Default maximum number of retransmissions per association"); 838 839 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, path_rtx_max, CTLFLAG_RW, 840 &sctp_path_rtx_max_default, 0, 841 "Default maximum of retransmissions per path"); 842 843 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, add_more_on_output, CTLFLAG_RW, 844 &sctp_add_more_threshold, 0, 845 "When space wise is it worthwhile to try to add more to a socket send buffer"); 846 847 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, nr_outgoing_streams, CTLFLAG_RW, 848 &sctp_nr_outgoing_streams_default, 0, 849 "Default number of outgoing streams"); 850 851 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cmt_on_off, CTLFLAG_RW, 852 &sctp_cmt_on_off, 0, 853 "CMT ON/OFF flag"); 854 855 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cwnd_maxburst, CTLFLAG_RW, 856 &sctp_use_cwnd_based_maxburst, 0, 857 "Use a CWND adjusting maxburst"); 858 859 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, early_fast_retran, CTLFLAG_RW, 860 &sctp_early_fr, 0, 861 "Early Fast Retransmit with Timer"); 862 863 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, use_rttvar_congctrl, CTLFLAG_RW, 864 &sctp_use_rttvar_cc, 0, 865 "Use congestion control via rtt variation"); 866 867 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, deadlock_detect, CTLFLAG_RW, 868 &sctp_says_check_for_deadlock, 0, 869 "SMP Deadlock detection on/off"); 870 871 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, early_fast_retran_msec, CTLFLAG_RW, 872 &sctp_early_fr_msec, 0, 873 "Early Fast Retransmit minimum timer value"); 874 875 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, asconf_auth_nochk, CTLFLAG_RW, 876 &sctp_asconf_auth_nochk, 0, 877 "Disable SCTP ASCONF AUTH requirement"); 878 879 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_disable, CTLFLAG_RW, 880 &sctp_auth_disable, 0, 881 "Disable SCTP AUTH chunk requirement/function"); 882 883 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_random_len, CTLFLAG_RW, 884 &sctp_auth_random_len, 0, 885 "Length of AUTH RANDOMs"); 886 887 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_hmac_id, CTLFLAG_RW, 888 &sctp_auth_hmac_id_default, 0, 889 "Default HMAC Id for SCTP AUTHenthication"); 890 891 SYSCTL_INT(_net_inet_sctp, OID_AUTO, abc_l_var, CTLFLAG_RW, 892 &sctp_L2_abc_variable, 0, 893 "SCTP ABC max increase per SACK (L)"); 894 895 SYSCTL_INT(_net_inet_sctp, OID_AUTO, max_chained_mbufs, CTLFLAG_RW, 896 &sctp_mbuf_threshold_count, 0, 897 "Default max number of small mbufs on a chain"); 898 899 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cmt_use_dac, CTLFLAG_RW, 900 &sctp_cmt_use_dac, 0, 901 "CMT DAC ON/OFF flag"); 902 903 SYSCTL_INT(_net_inet_sctp, OID_AUTO, do_sctp_drain, CTLFLAG_RW, 904 &sctp_do_drain, 0, 905 "Should SCTP respond to the drain calls"); 906 907 SYSCTL_INT(_net_inet_sctp, OID_AUTO, warm_crc_table, CTLFLAG_RW, 908 &sctp_warm_the_crc32_table, 0, 909 "Should the CRC32c tables be warmed before checksum?"); 910 911 SYSCTL_INT(_net_inet_sctp, OID_AUTO, abort_at_limit, CTLFLAG_RW, 912 &sctp_abort_if_one_2_one_hits_limit, 0, 913 "When one-2-one hits qlimit abort"); 914 915 SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_data_order, CTLFLAG_RW, 916 &sctp_strict_data_order, 0, 917 "Enforce strict data ordering, abort if control inside data"); 918 919 SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW, 920 &sctpstat, sctpstat, 921 "SCTP statistics (struct sctps_stat, netinet/sctp.h"); 922 923 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD, 924 0, 0, sctp_assoclist, 925 "S,xassoc", "List of active SCTP associations"); 926 927 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, nat_friendly, CTLFLAG_RW, 928 &sctp_nat_friendly, 0, 929 "SCTP NAT friendly operation"); 930 931 #ifdef SCTP_DEBUG 932 SYSCTL_INT(_net_inet_sctp, OID_AUTO, debug, CTLFLAG_RW, 933 &sctp_debug_on, 0, "Configure debug output"); 934 #endif /* SCTP_DEBUG */ 935 936 static void 937 sctp_abort(struct socket *so) 938 { 939 struct sctp_inpcb *inp; 940 int s; 941 uint32_t flags; 942 943 inp = (struct sctp_inpcb *)so->so_pcb; 944 if (inp == 0) 945 return; 946 947 s = splnet(); 948 sctp_must_try_again: 949 flags = inp->sctp_flags; 950 #ifdef SCTP_LOG_CLOSING 951 sctp_log_closing(inp, NULL, 17); 952 #endif 953 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 954 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 955 #ifdef SCTP_LOG_CLOSING 956 sctp_log_closing(inp, NULL, 16); 957 #endif 958 sctp_inpcb_free(inp, 1, 0); 959 SOCK_LOCK(so); 960 so->so_snd.sb_cc = 0; 961 so->so_snd.sb_mb = NULL; 962 so->so_snd.sb_mbcnt = 0; 963 964 /* 965 * same for the rcv ones, they are only here for the 966 * accounting/select. 967 */ 968 so->so_rcv.sb_cc = 0; 969 so->so_rcv.sb_mb = NULL; 970 so->so_rcv.sb_mbcnt = 0; 971 /* 972 * Now null out the reference, we are completely detached. 973 */ 974 so->so_pcb = NULL; 975 SOCK_UNLOCK(so); 976 977 } else { 978 flags = inp->sctp_flags; 979 if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 980 goto sctp_must_try_again; 981 } 982 } 983 splx(s); 984 return; 985 } 986 987 static int 988 sctp_attach(struct socket *so, int proto, struct thread *p) 989 { 990 struct sctp_inpcb *inp; 991 struct inpcb *ip_inp; 992 int s, error; 993 994 #ifdef IPSEC 995 uint32_t flags; 996 997 #endif 998 s = splnet(); 999 inp = (struct sctp_inpcb *)so->so_pcb; 1000 if (inp != 0) { 1001 splx(s); 1002 return EINVAL; 1003 } 1004 error = soreserve(so, sctp_sendspace, sctp_recvspace); 1005 if (error) { 1006 splx(s); 1007 return error; 1008 } 1009 error = sctp_inpcb_alloc(so); 1010 if (error) { 1011 splx(s); 1012 return error; 1013 } 1014 inp = (struct sctp_inpcb *)so->so_pcb; 1015 SCTP_INP_WLOCK(inp); 1016 1017 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */ 1018 ip_inp = &inp->ip_inp.inp; 1019 ip_inp->inp_vflag |= INP_IPV4; 1020 ip_inp->inp_ip_ttl = ip_defttl; 1021 1022 #ifdef IPSEC 1023 error = ipsec_init_pcbpolicy(so, &ip_inp->inp_sp); 1024 #ifdef SCTP_LOG_CLOSING 1025 sctp_log_closing(inp, NULL, 17); 1026 #endif 1027 if (error != 0) { 1028 flags = inp->sctp_flags; 1029 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 1030 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 1031 #ifdef SCTP_LOG_CLOSING 1032 sctp_log_closing(inp, NULL, 15); 1033 #endif 1034 sctp_inpcb_free(inp, 1, 0); 1035 } 1036 return error; 1037 } 1038 #endif /* IPSEC */ 1039 SCTP_INP_WUNLOCK(inp); 1040 splx(s); 1041 return 0; 1042 } 1043 1044 static int 1045 sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p) 1046 { 1047 struct sctp_inpcb *inp; 1048 int s, error; 1049 1050 #ifdef INET6 1051 if (addr && addr->sa_family != AF_INET) 1052 /* must be a v4 address! */ 1053 return EINVAL; 1054 #endif /* INET6 */ 1055 1056 inp = (struct sctp_inpcb *)so->so_pcb; 1057 if (inp == 0) 1058 return EINVAL; 1059 1060 s = splnet(); 1061 error = sctp_inpcb_bind(so, addr, p); 1062 splx(s); 1063 return error; 1064 } 1065 1066 static void 1067 sctp_close(struct socket *so) 1068 { 1069 struct sctp_inpcb *inp; 1070 uint32_t flags; 1071 1072 inp = (struct sctp_inpcb *)so->so_pcb; 1073 if (inp == 0) 1074 return; 1075 1076 /* 1077 * Inform all the lower layer assoc that we are done. 1078 */ 1079 sctp_must_try_again: 1080 flags = inp->sctp_flags; 1081 #ifdef SCTP_LOG_CLOSING 1082 sctp_log_closing(inp, NULL, 17); 1083 #endif 1084 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 1085 (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 1086 if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) || 1087 (so->so_rcv.sb_cc > 0)) { 1088 #ifdef SCTP_LOG_CLOSING 1089 sctp_log_closing(inp, NULL, 13); 1090 #endif 1091 sctp_inpcb_free(inp, 1, 1); 1092 } else { 1093 #ifdef SCTP_LOG_CLOSING 1094 sctp_log_closing(inp, NULL, 14); 1095 #endif 1096 sctp_inpcb_free(inp, 0, 1); 1097 } 1098 /* 1099 * The socket is now detached, no matter what the state of 1100 * the SCTP association. 1101 */ 1102 SOCK_LOCK(so); 1103 so->so_snd.sb_cc = 0; 1104 so->so_snd.sb_mb = NULL; 1105 so->so_snd.sb_mbcnt = 0; 1106 1107 /* 1108 * same for the rcv ones, they are only here for the 1109 * accounting/select. 1110 */ 1111 so->so_rcv.sb_cc = 0; 1112 so->so_rcv.sb_mb = NULL; 1113 so->so_rcv.sb_mbcnt = 0; 1114 /* 1115 * Now null out the reference, we are completely detached. 1116 */ 1117 so->so_pcb = NULL; 1118 SOCK_UNLOCK(so); 1119 } else { 1120 flags = inp->sctp_flags; 1121 if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 1122 goto sctp_must_try_again; 1123 } 1124 } 1125 return; 1126 } 1127 1128 1129 int 1130 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 1131 struct mbuf *control, struct thread *p); 1132 1133 1134 int 1135 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 1136 struct mbuf *control, struct thread *p) 1137 { 1138 struct sctp_inpcb *inp; 1139 int error; 1140 1141 inp = (struct sctp_inpcb *)so->so_pcb; 1142 if (inp == 0) { 1143 if (control) { 1144 sctp_m_freem(control); 1145 control = NULL; 1146 } 1147 sctp_m_freem(m); 1148 return EINVAL; 1149 } 1150 /* Got to have an to address if we are NOT a connected socket */ 1151 if ((addr == NULL) && 1152 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) || 1153 (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) 1154 ) { 1155 goto connected_type; 1156 } else if (addr == NULL) { 1157 error = EDESTADDRREQ; 1158 sctp_m_freem(m); 1159 if (control) { 1160 sctp_m_freem(control); 1161 control = NULL; 1162 } 1163 return (error); 1164 } 1165 #ifdef INET6 1166 if (addr->sa_family != AF_INET) { 1167 /* must be a v4 address! */ 1168 sctp_m_freem(m); 1169 if (control) { 1170 sctp_m_freem(control); 1171 control = NULL; 1172 } 1173 error = EDESTADDRREQ; 1174 return EINVAL; 1175 } 1176 #endif /* INET6 */ 1177 connected_type: 1178 /* now what about control */ 1179 if (control) { 1180 if (inp->control) { 1181 printf("huh? control set?\n"); 1182 sctp_m_freem(inp->control); 1183 inp->control = NULL; 1184 } 1185 inp->control = control; 1186 } 1187 /* Place the data */ 1188 if (inp->pkt) { 1189 SCTP_BUF_NEXT(inp->pkt_last) = m; 1190 inp->pkt_last = m; 1191 } else { 1192 inp->pkt_last = inp->pkt = m; 1193 } 1194 if ( 1195 /* FreeBSD uses a flag passed */ 1196 ((flags & PRUS_MORETOCOME) == 0) 1197 ) { 1198 /* 1199 * note with the current version this code will only be used 1200 * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for 1201 * re-defining sosend to use the sctp_sosend. One can 1202 * optionally switch back to this code (by changing back the 1203 * definitions) but this is not advisable. This code is used 1204 * by FreeBSD when sending a file with sendfile() though. 1205 */ 1206 int ret; 1207 1208 ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags); 1209 inp->pkt = NULL; 1210 inp->control = NULL; 1211 return (ret); 1212 } else { 1213 return (0); 1214 } 1215 } 1216 1217 static int 1218 sctp_disconnect(struct socket *so) 1219 { 1220 struct sctp_inpcb *inp; 1221 int s; 1222 1223 s = splnet(); 1224 inp = (struct sctp_inpcb *)so->so_pcb; 1225 if (inp == NULL) { 1226 splx(s); 1227 return (ENOTCONN); 1228 } 1229 SCTP_INP_RLOCK(inp); 1230 if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 1231 if (LIST_EMPTY(&inp->sctp_asoc_list)) { 1232 /* No connection */ 1233 splx(s); 1234 SCTP_INP_RUNLOCK(inp); 1235 return (0); 1236 } else { 1237 struct sctp_association *asoc; 1238 struct sctp_tcb *stcb; 1239 1240 stcb = LIST_FIRST(&inp->sctp_asoc_list); 1241 if (stcb == NULL) { 1242 splx(s); 1243 SCTP_INP_RUNLOCK(inp); 1244 return (EINVAL); 1245 } 1246 SCTP_TCB_LOCK(stcb); 1247 asoc = &stcb->asoc; 1248 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 1249 /* We are about to be freed, out of here */ 1250 SCTP_TCB_UNLOCK(stcb); 1251 SCTP_INP_RUNLOCK(inp); 1252 return (0); 1253 } 1254 if (((so->so_options & SO_LINGER) && 1255 (so->so_linger == 0)) || 1256 (so->so_rcv.sb_cc > 0)) { 1257 if (SCTP_GET_STATE(asoc) != 1258 SCTP_STATE_COOKIE_WAIT) { 1259 /* Left with Data unread */ 1260 struct mbuf *err; 1261 1262 err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_DONTWAIT, 1, MT_DATA); 1263 if (err) { 1264 /* 1265 * Fill in the user 1266 * initiated abort 1267 */ 1268 struct sctp_paramhdr *ph; 1269 1270 ph = mtod(err, struct sctp_paramhdr *); 1271 SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr); 1272 ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); 1273 ph->param_length = htons(SCTP_BUF_LEN(err)); 1274 } 1275 sctp_send_abort_tcb(stcb, err); 1276 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 1277 } 1278 SCTP_INP_RUNLOCK(inp); 1279 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 1280 (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 1281 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 1282 } 1283 sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3); 1284 /* No unlock tcb assoc is gone */ 1285 splx(s); 1286 return (0); 1287 } 1288 if (TAILQ_EMPTY(&asoc->send_queue) && 1289 TAILQ_EMPTY(&asoc->sent_queue) && 1290 (asoc->stream_queue_cnt == 0)) { 1291 /* there is nothing queued to send, so done */ 1292 if (asoc->locked_on_sending) { 1293 goto abort_anyway; 1294 } 1295 if ((SCTP_GET_STATE(asoc) != 1296 SCTP_STATE_SHUTDOWN_SENT) && 1297 (SCTP_GET_STATE(asoc) != 1298 SCTP_STATE_SHUTDOWN_ACK_SENT)) { 1299 /* only send SHUTDOWN 1st time thru */ 1300 sctp_stop_timers_for_shutdown(stcb); 1301 sctp_send_shutdown(stcb, 1302 stcb->asoc.primary_destination); 1303 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3); 1304 asoc->state = SCTP_STATE_SHUTDOWN_SENT; 1305 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 1306 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 1307 stcb->sctp_ep, stcb, 1308 asoc->primary_destination); 1309 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 1310 stcb->sctp_ep, stcb, 1311 asoc->primary_destination); 1312 } 1313 } else { 1314 /* 1315 * we still got (or just got) data to send, 1316 * so set SHUTDOWN_PENDING 1317 */ 1318 /* 1319 * XXX sockets draft says that SCTP_EOF 1320 * should be sent with no data. currently, 1321 * we will allow user data to be sent first 1322 * and move to SHUTDOWN-PENDING 1323 */ 1324 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING; 1325 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, 1326 asoc->primary_destination); 1327 if (asoc->locked_on_sending) { 1328 /* Locked to send out the data */ 1329 struct sctp_stream_queue_pending *sp; 1330 1331 sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead); 1332 if (sp == NULL) { 1333 printf("Error, sp is NULL, locked on sending is non-null strm:%d\n", 1334 asoc->locked_on_sending->stream_no); 1335 } else { 1336 if ((sp->length == 0) && (sp->msg_is_complete == 0)) 1337 asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT; 1338 } 1339 } 1340 if (TAILQ_EMPTY(&asoc->send_queue) && 1341 TAILQ_EMPTY(&asoc->sent_queue) && 1342 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 1343 struct mbuf *op_err; 1344 1345 abort_anyway: 1346 op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), 1347 0, M_DONTWAIT, 1, MT_DATA); 1348 if (op_err) { 1349 /* 1350 * Fill in the user 1351 * initiated abort 1352 */ 1353 struct sctp_paramhdr *ph; 1354 uint32_t *ippp; 1355 1356 SCTP_BUF_LEN(op_err) = 1357 (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)); 1358 ph = mtod(op_err, 1359 struct sctp_paramhdr *); 1360 ph->param_type = htons( 1361 SCTP_CAUSE_USER_INITIATED_ABT); 1362 ph->param_length = htons(SCTP_BUF_LEN(op_err)); 1363 ippp = (uint32_t *) (ph + 1); 1364 *ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4); 1365 } 1366 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4; 1367 sctp_send_abort_tcb(stcb, op_err); 1368 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 1369 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 1370 (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 1371 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 1372 } 1373 SCTP_INP_RUNLOCK(inp); 1374 sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5); 1375 splx(s); 1376 return (0); 1377 } 1378 } 1379 SCTP_TCB_UNLOCK(stcb); 1380 SCTP_INP_RUNLOCK(inp); 1381 splx(s); 1382 return (0); 1383 } 1384 /* not reached */ 1385 } else { 1386 /* UDP model does not support this */ 1387 SCTP_INP_RUNLOCK(inp); 1388 splx(s); 1389 return EOPNOTSUPP; 1390 } 1391 } 1392 1393 int 1394 sctp_shutdown(struct socket *so) 1395 { 1396 struct sctp_inpcb *inp; 1397 int s; 1398 1399 s = splnet(); 1400 inp = (struct sctp_inpcb *)so->so_pcb; 1401 if (inp == 0) { 1402 splx(s); 1403 return EINVAL; 1404 } 1405 SCTP_INP_RLOCK(inp); 1406 /* For UDP model this is a invalid call */ 1407 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 1408 /* Restore the flags that the soshutdown took away. */ 1409 so->so_rcv.sb_state &= ~SBS_CANTRCVMORE; 1410 /* This proc will wakeup for read and do nothing (I hope) */ 1411 splx(s); 1412 SCTP_INP_RUNLOCK(inp); 1413 return (EOPNOTSUPP); 1414 } 1415 /* 1416 * Ok if we reach here its the TCP model and it is either a SHUT_WR 1417 * or SHUT_RDWR. This means we put the shutdown flag against it. 1418 */ 1419 { 1420 struct sctp_tcb *stcb; 1421 struct sctp_association *asoc; 1422 1423 socantsendmore(so); 1424 1425 stcb = LIST_FIRST(&inp->sctp_asoc_list); 1426 if (stcb == NULL) { 1427 /* 1428 * Ok we hit the case that the shutdown call was 1429 * made after an abort or something. Nothing to do 1430 * now. 1431 */ 1432 splx(s); 1433 return (0); 1434 } 1435 SCTP_TCB_LOCK(stcb); 1436 asoc = &stcb->asoc; 1437 if (TAILQ_EMPTY(&asoc->send_queue) && 1438 TAILQ_EMPTY(&asoc->sent_queue) && 1439 (asoc->stream_queue_cnt == 0)) { 1440 if (asoc->locked_on_sending) { 1441 goto abort_anyway; 1442 } 1443 /* there is nothing queued to send, so I'm done... */ 1444 if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) { 1445 /* only send SHUTDOWN the first time through */ 1446 sctp_stop_timers_for_shutdown(stcb); 1447 sctp_send_shutdown(stcb, 1448 stcb->asoc.primary_destination); 1449 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3); 1450 asoc->state = SCTP_STATE_SHUTDOWN_SENT; 1451 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 1452 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 1453 stcb->sctp_ep, stcb, 1454 asoc->primary_destination); 1455 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 1456 stcb->sctp_ep, stcb, 1457 asoc->primary_destination); 1458 } 1459 } else { 1460 /* 1461 * we still got (or just got) data to send, so set 1462 * SHUTDOWN_PENDING 1463 */ 1464 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING; 1465 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, 1466 asoc->primary_destination); 1467 1468 if (asoc->locked_on_sending) { 1469 /* Locked to send out the data */ 1470 struct sctp_stream_queue_pending *sp; 1471 1472 sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead); 1473 if (sp == NULL) { 1474 printf("Error, sp is NULL, locked on sending is non-null strm:%d\n", 1475 asoc->locked_on_sending->stream_no); 1476 } else { 1477 if ((sp->length == 0) && (sp->msg_is_complete == 0)) { 1478 asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT; 1479 } 1480 } 1481 } 1482 if (TAILQ_EMPTY(&asoc->send_queue) && 1483 TAILQ_EMPTY(&asoc->sent_queue) && 1484 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 1485 struct mbuf *op_err; 1486 1487 abort_anyway: 1488 op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), 1489 0, M_DONTWAIT, 1, MT_DATA); 1490 if (op_err) { 1491 /* Fill in the user initiated abort */ 1492 struct sctp_paramhdr *ph; 1493 uint32_t *ippp; 1494 1495 SCTP_BUF_LEN(op_err) = 1496 sizeof(struct sctp_paramhdr) + sizeof(uint32_t); 1497 ph = mtod(op_err, 1498 struct sctp_paramhdr *); 1499 ph->param_type = htons( 1500 SCTP_CAUSE_USER_INITIATED_ABT); 1501 ph->param_length = htons(SCTP_BUF_LEN(op_err)); 1502 ippp = (uint32_t *) (ph + 1); 1503 *ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6); 1504 } 1505 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6; 1506 sctp_abort_an_association(stcb->sctp_ep, stcb, 1507 SCTP_RESPONSE_TO_USER_REQ, 1508 op_err); 1509 goto skip_unlock; 1510 } 1511 } 1512 SCTP_TCB_UNLOCK(stcb); 1513 } 1514 skip_unlock: 1515 SCTP_INP_RUNLOCK(inp); 1516 splx(s); 1517 return 0; 1518 } 1519 1520 /* 1521 * copies a "user" presentable address and removes embedded scope, etc. 1522 * returns 0 on success, 1 on error 1523 */ 1524 static uint32_t 1525 sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa) 1526 { 1527 struct sockaddr_in6 lsa6; 1528 1529 sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa, 1530 &lsa6); 1531 memcpy(ss, sa, sa->sa_len); 1532 return (0); 1533 } 1534 1535 1536 1537 static int 1538 sctp_fill_up_addresses(struct sctp_inpcb *inp, 1539 struct sctp_tcb *stcb, 1540 int limit, 1541 struct sockaddr_storage *sas) 1542 { 1543 struct ifnet *ifn; 1544 struct ifaddr *ifa; 1545 int loopback_scope, ipv4_local_scope, local_scope, site_scope, actual; 1546 int ipv4_addr_legal, ipv6_addr_legal; 1547 1548 actual = 0; 1549 if (limit <= 0) 1550 return (actual); 1551 1552 if (stcb) { 1553 /* Turn on all the appropriate scope */ 1554 loopback_scope = stcb->asoc.loopback_scope; 1555 ipv4_local_scope = stcb->asoc.ipv4_local_scope; 1556 local_scope = stcb->asoc.local_scope; 1557 site_scope = stcb->asoc.site_scope; 1558 } else { 1559 /* Turn on ALL scope, since we look at the EP */ 1560 loopback_scope = ipv4_local_scope = local_scope = 1561 site_scope = 1; 1562 } 1563 ipv4_addr_legal = ipv6_addr_legal = 0; 1564 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1565 ipv6_addr_legal = 1; 1566 if ( 1567 (((struct in6pcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY) 1568 == 0) { 1569 ipv4_addr_legal = 1; 1570 } 1571 } else { 1572 ipv4_addr_legal = 1; 1573 } 1574 1575 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1576 TAILQ_FOREACH(ifn, &ifnet, if_list) { 1577 if ((loopback_scope == 0) && 1578 (ifn->if_type == IFT_LOOP)) { 1579 /* Skip loopback if loopback_scope not set */ 1580 continue; 1581 } 1582 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1583 if (stcb) { 1584 /* 1585 * For the BOUND-ALL case, the list 1586 * associated with a TCB is Always 1587 * considered a reverse list.. i.e. 1588 * it lists addresses that are NOT 1589 * part of the association. If this 1590 * is one of those we must skip it. 1591 */ 1592 if (sctp_is_addr_restricted(stcb, 1593 ifa->ifa_addr)) { 1594 continue; 1595 } 1596 } 1597 if ((ifa->ifa_addr->sa_family == AF_INET) && 1598 (ipv4_addr_legal)) { 1599 struct sockaddr_in *sin; 1600 1601 sin = (struct sockaddr_in *)ifa->ifa_addr; 1602 if (sin->sin_addr.s_addr == 0) { 1603 /* 1604 * we skip unspecifed 1605 * addresses 1606 */ 1607 continue; 1608 } 1609 if ((ipv4_local_scope == 0) && 1610 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 1611 continue; 1612 } 1613 if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) { 1614 in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas); 1615 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1616 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6)); 1617 actual += sizeof(sizeof(struct sockaddr_in6)); 1618 } else { 1619 memcpy(sas, sin, sizeof(*sin)); 1620 ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 1621 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin)); 1622 actual += sizeof(*sin); 1623 } 1624 if (actual >= limit) { 1625 return (actual); 1626 } 1627 } else if ((ifa->ifa_addr->sa_family == AF_INET6) && 1628 (ipv6_addr_legal)) { 1629 struct sockaddr_in6 *sin6; 1630 1631 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 1632 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1633 /* 1634 * we skip unspecifed 1635 * addresses 1636 */ 1637 continue; 1638 } 1639 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 1640 if (local_scope == 0) 1641 continue; 1642 if (sin6->sin6_scope_id == 0) { 1643 if (sa6_recoverscope(sin6) != 0) 1644 /* 1645 * bad link 1646 * local 1647 * address 1648 */ 1649 continue; 1650 } 1651 } 1652 if ((site_scope == 0) && 1653 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 1654 continue; 1655 } 1656 memcpy(sas, sin6, sizeof(*sin6)); 1657 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1658 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6)); 1659 actual += sizeof(*sin6); 1660 if (actual >= limit) { 1661 return (actual); 1662 } 1663 } 1664 } 1665 } 1666 } else { 1667 struct sctp_laddr *laddr; 1668 1669 /* 1670 * If we have a TCB and we do NOT support ASCONF (it's 1671 * turned off or otherwise) then the list is always the true 1672 * list of addresses (the else case below). Otherwise the 1673 * list on the association is a list of addresses that are 1674 * NOT part of the association. 1675 */ 1676 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) { 1677 /* The list is a NEGATIVE list */ 1678 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1679 if (stcb) { 1680 if (sctp_is_addr_restricted(stcb, laddr->ifa->ifa_addr)) { 1681 continue; 1682 } 1683 } 1684 if (sctp_fill_user_address(sas, laddr->ifa->ifa_addr)) 1685 continue; 1686 1687 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1688 sas = (struct sockaddr_storage *)((caddr_t)sas + 1689 laddr->ifa->ifa_addr->sa_len); 1690 actual += laddr->ifa->ifa_addr->sa_len; 1691 if (actual >= limit) { 1692 return (actual); 1693 } 1694 } 1695 } else { 1696 /* The list is a positive list if present */ 1697 if (stcb) { 1698 /* Must use the specific association list */ 1699 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 1700 sctp_nxt_addr) { 1701 if (sctp_fill_user_address(sas, 1702 laddr->ifa->ifa_addr)) 1703 continue; 1704 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1705 sas = (struct sockaddr_storage *)((caddr_t)sas + 1706 laddr->ifa->ifa_addr->sa_len); 1707 actual += laddr->ifa->ifa_addr->sa_len; 1708 if (actual >= limit) { 1709 return (actual); 1710 } 1711 } 1712 } else { 1713 /* 1714 * No endpoint so use the endpoints 1715 * individual list 1716 */ 1717 LIST_FOREACH(laddr, &inp->sctp_addr_list, 1718 sctp_nxt_addr) { 1719 if (sctp_fill_user_address(sas, 1720 laddr->ifa->ifa_addr)) 1721 continue; 1722 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 1723 sas = (struct sockaddr_storage *)((caddr_t)sas + 1724 laddr->ifa->ifa_addr->sa_len); 1725 actual += laddr->ifa->ifa_addr->sa_len; 1726 if (actual >= limit) { 1727 return (actual); 1728 } 1729 } 1730 } 1731 } 1732 } 1733 return (actual); 1734 } 1735 1736 static int 1737 sctp_count_max_addresses(struct sctp_inpcb *inp) 1738 { 1739 int cnt = 0; 1740 1741 /* 1742 * In both sub-set bound an bound_all cases we return the MAXIMUM 1743 * number of addresses that you COULD get. In reality the sub-set 1744 * bound may have an exclusion list for a given TCB OR in the 1745 * bound-all case a TCB may NOT include the loopback or other 1746 * addresses as well. 1747 */ 1748 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1749 struct ifnet *ifn; 1750 struct ifaddr *ifa; 1751 1752 TAILQ_FOREACH(ifn, &ifnet, if_list) { 1753 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1754 /* Count them if they are the right type */ 1755 if (ifa->ifa_addr->sa_family == AF_INET) { 1756 if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) 1757 cnt += sizeof(struct sockaddr_in6); 1758 else 1759 cnt += sizeof(struct sockaddr_in); 1760 1761 } else if (ifa->ifa_addr->sa_family == AF_INET6) 1762 cnt += sizeof(struct sockaddr_in6); 1763 } 1764 } 1765 } else { 1766 struct sctp_laddr *laddr; 1767 1768 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1769 if (laddr->ifa->ifa_addr->sa_family == AF_INET) { 1770 if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) 1771 cnt += sizeof(struct sockaddr_in6); 1772 else 1773 cnt += sizeof(struct sockaddr_in); 1774 1775 } else if (laddr->ifa->ifa_addr->sa_family == AF_INET6) 1776 cnt += sizeof(struct sockaddr_in6); 1777 } 1778 } 1779 return (cnt); 1780 } 1781 1782 static int 1783 sctp_do_connect_x(struct socket *so, 1784 struct sctp_inpcb *inp, 1785 struct mbuf *m, 1786 struct thread *p, 1787 int delay 1788 ) 1789 { 1790 int s = splnet(); 1791 1792 int error = 0; 1793 int creat_lock_on = 0; 1794 struct sctp_tcb *stcb = NULL; 1795 struct sockaddr *sa; 1796 int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr, i, incr, at; 1797 1798 #ifdef SCTP_DEBUG 1799 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 1800 printf("Connectx called\n"); 1801 } 1802 #endif /* SCTP_DEBUG */ 1803 1804 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 1805 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 1806 /* We are already connected AND the TCP model */ 1807 splx(s); 1808 return (EADDRINUSE); 1809 } 1810 if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) { 1811 splx(s); 1812 return (EINVAL); 1813 } 1814 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 1815 SCTP_INP_RLOCK(inp); 1816 stcb = LIST_FIRST(&inp->sctp_asoc_list); 1817 SCTP_INP_RUNLOCK(inp); 1818 } 1819 if (stcb) { 1820 splx(s); 1821 return (EALREADY); 1822 1823 } 1824 SCTP_INP_INCR_REF(inp); 1825 SCTP_ASOC_CREATE_LOCK(inp); 1826 creat_lock_on = 1; 1827 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 1828 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 1829 error = EFAULT; 1830 goto out_now; 1831 } 1832 totaddrp = mtod(m, int *); 1833 totaddr = *totaddrp; 1834 sa = (struct sockaddr *)(totaddrp + 1); 1835 at = incr = 0; 1836 /* account and validate addresses */ 1837 for (i = 0; i < totaddr; i++) { 1838 if (sa->sa_family == AF_INET) { 1839 num_v4++; 1840 incr = sizeof(struct sockaddr_in); 1841 } else if (sa->sa_family == AF_INET6) { 1842 struct sockaddr_in6 *sin6; 1843 1844 sin6 = (struct sockaddr_in6 *)sa; 1845 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 1846 /* Must be non-mapped for connectx */ 1847 error = EINVAL; 1848 goto out_now; 1849 } 1850 num_v6++; 1851 incr = sizeof(struct sockaddr_in6); 1852 } else { 1853 totaddr = i; 1854 break; 1855 } 1856 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL); 1857 if (stcb != NULL) { 1858 /* Already have or am bring up an association */ 1859 SCTP_ASOC_CREATE_UNLOCK(inp); 1860 creat_lock_on = 0; 1861 SCTP_TCB_UNLOCK(stcb); 1862 error = EALREADY; 1863 goto out_now; 1864 } 1865 if ((at + incr) > SCTP_BUF_LEN(m)) { 1866 totaddr = i; 1867 break; 1868 } 1869 sa = (struct sockaddr *)((caddr_t)sa + incr); 1870 } 1871 sa = (struct sockaddr *)(totaddrp + 1); 1872 #ifdef INET6 1873 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 1874 (num_v6 > 0)) { 1875 splx(s); 1876 error = EINVAL; 1877 goto out_now; 1878 } 1879 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 1880 (num_v4 > 0)) { 1881 struct in6pcb *inp6; 1882 1883 inp6 = (struct in6pcb *)inp; 1884 if ( 1885 (inp6->inp_flags & IN6P_IPV6_V6ONLY) 1886 ) { 1887 /* 1888 * if IPV6_V6ONLY flag, ignore connections destined 1889 * to a v4 addr or v4-mapped addr 1890 */ 1891 error = EINVAL; 1892 goto out_now; 1893 } 1894 } 1895 #endif /* INET6 */ 1896 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 1897 SCTP_PCB_FLAGS_UNBOUND) { 1898 /* Bind a ephemeral port */ 1899 SCTP_INP_WUNLOCK(inp); 1900 error = sctp_inpcb_bind(so, NULL, p); 1901 if (error) { 1902 goto out_now; 1903 } 1904 } else { 1905 SCTP_INP_WUNLOCK(inp); 1906 } 1907 1908 /* We are GOOD to go */ 1909 stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0); 1910 if (stcb == NULL) { 1911 /* Gak! no memory */ 1912 goto out_now; 1913 } 1914 /* move to second address */ 1915 if (sa->sa_family == AF_INET) 1916 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in)); 1917 else 1918 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6)); 1919 1920 for (i = 1; i < totaddr; i++) { 1921 if (sa->sa_family == AF_INET) { 1922 incr = sizeof(struct sockaddr_in); 1923 if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) { 1924 /* assoc gone no un-lock */ 1925 sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7); 1926 error = ENOBUFS; 1927 goto out_now; 1928 } 1929 } else if (sa->sa_family == AF_INET6) { 1930 incr = sizeof(struct sockaddr_in6); 1931 if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) { 1932 /* assoc gone no un-lock */ 1933 sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8); 1934 error = ENOBUFS; 1935 goto out_now; 1936 } 1937 } 1938 sa = (struct sockaddr *)((caddr_t)sa + incr); 1939 } 1940 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT; 1941 1942 /* initialize authentication parameters for the assoc */ 1943 sctp_initialize_auth_params(inp, stcb); 1944 1945 if (delay) { 1946 /* doing delayed connection */ 1947 stcb->asoc.delayed_connection = 1; 1948 sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination); 1949 } else { 1950 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 1951 sctp_send_initiate(inp, stcb); 1952 } 1953 SCTP_TCB_UNLOCK(stcb); 1954 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 1955 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 1956 /* Set the connected flag so we can queue data */ 1957 soisconnecting(so); 1958 } 1959 out_now: 1960 if (creat_lock_on) 1961 SCTP_ASOC_CREATE_UNLOCK(inp); 1962 SCTP_INP_DECR_REF(inp); 1963 splx(s); 1964 return error; 1965 } 1966 1967 1968 1969 static int 1970 sctp_optsget(struct socket *so, 1971 int opt, 1972 struct mbuf **mp, 1973 struct thread *p 1974 ) 1975 { 1976 struct sctp_inpcb *inp; 1977 struct mbuf *m; 1978 int error, optval = 0; 1979 struct sctp_tcb *stcb = NULL; 1980 1981 inp = (struct sctp_inpcb *)so->so_pcb; 1982 if (inp == 0) 1983 return EINVAL; 1984 error = 0; 1985 1986 if (mp == NULL) { 1987 return (EINVAL); 1988 } 1989 m = *mp; 1990 if (m == NULL) { 1991 /* Got to have a mbuf */ 1992 return (EINVAL); 1993 } 1994 switch (opt) { 1995 case SCTP_NODELAY: 1996 case SCTP_AUTOCLOSE: 1997 case SCTP_EXPLICIT_EOR: 1998 case SCTP_AUTO_ASCONF: 1999 case SCTP_DISABLE_FRAGMENTS: 2000 case SCTP_I_WANT_MAPPED_V4_ADDR: 2001 case SCTP_USE_EXT_RCVINFO: 2002 SCTP_INP_RLOCK(inp); 2003 switch (opt) { 2004 case SCTP_DISABLE_FRAGMENTS: 2005 optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT); 2006 break; 2007 case SCTP_I_WANT_MAPPED_V4_ADDR: 2008 optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4); 2009 break; 2010 case SCTP_AUTO_ASCONF: 2011 optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 2012 break; 2013 case SCTP_EXPLICIT_EOR: 2014 optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); 2015 break; 2016 case SCTP_NODELAY: 2017 optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY); 2018 break; 2019 case SCTP_USE_EXT_RCVINFO: 2020 optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO); 2021 break; 2022 case SCTP_AUTOCLOSE: 2023 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) 2024 optval = TICKS_TO_SEC(inp->sctp_ep.auto_close_time); 2025 else 2026 optval = 0; 2027 break; 2028 2029 default: 2030 error = ENOPROTOOPT; 2031 } /* end switch (sopt->sopt_name) */ 2032 if (opt != SCTP_AUTOCLOSE) { 2033 /* make it an "on/off" value */ 2034 optval = (optval != 0); 2035 } 2036 if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) { 2037 error = EINVAL; 2038 } 2039 SCTP_INP_RUNLOCK(inp); 2040 if (error == 0) { 2041 /* return the option value */ 2042 *mtod(m, int *)= optval; 2043 SCTP_BUF_LEN(m) = sizeof(optval); 2044 } 2045 break; 2046 case SCTP_PARTIAL_DELIVERY_POINT: 2047 { 2048 if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) { 2049 error = EINVAL; 2050 break; 2051 } 2052 *mtod(m, unsigned int *)= inp->partial_delivery_point; 2053 SCTP_BUF_LEN(m) = sizeof(unsigned int); 2054 } 2055 break; 2056 case SCTP_FRAGMENT_INTERLEAVE: 2057 { 2058 if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) { 2059 error = EINVAL; 2060 break; 2061 } 2062 *mtod(m, unsigned int *)= sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 2063 SCTP_BUF_LEN(m) = sizeof(unsigned int); 2064 } 2065 break; 2066 case SCTP_CMT_ON_OFF: 2067 { 2068 if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) { 2069 error = EINVAL; 2070 break; 2071 } 2072 *mtod(m, unsigned int *)= sctp_cmt_sockopt_on_off; 2073 SCTP_BUF_LEN(m) = sizeof(unsigned int); 2074 } 2075 break; 2076 case SCTP_CMT_USE_DAC: 2077 { 2078 *mtod(m, unsigned int *)= sctp_cmt_sockopt_use_dac; 2079 SCTP_BUF_LEN(m) = sizeof(unsigned int); 2080 } 2081 break; 2082 case SCTP_GET_ADDR_LEN: 2083 { 2084 struct sctp_assoc_value *av; 2085 2086 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) { 2087 error = EINVAL; 2088 break; 2089 } 2090 av = mtod(m, struct sctp_assoc_value *); 2091 error = EINVAL; 2092 #ifdef AF_INET 2093 if (av->assoc_value == AF_INET) { 2094 av->assoc_value = sizeof(struct sockaddr_in); 2095 error = 0; 2096 } 2097 #endif 2098 #ifdef AF_INET6 2099 if (av->assoc_value == AF_INET6) { 2100 av->assoc_value = sizeof(struct sockaddr_in6); 2101 error = 0; 2102 } 2103 #endif 2104 } 2105 break; 2106 case SCTP_GET_ASOC_ID_LIST: 2107 { 2108 struct sctp_assoc_ids *ids; 2109 int cnt, at; 2110 uint16_t orig; 2111 2112 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_ids)) { 2113 error = EINVAL; 2114 break; 2115 } 2116 ids = mtod(m, struct sctp_assoc_ids *); 2117 cnt = 0; 2118 SCTP_INP_RLOCK(inp); 2119 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2120 if (stcb == NULL) { 2121 none_out_now: 2122 ids->asls_numb_present = 0; 2123 ids->asls_more_to_get = 0; 2124 SCTP_INP_RUNLOCK(inp); 2125 break; 2126 } 2127 orig = ids->asls_assoc_start; 2128 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2129 while (orig) { 2130 stcb = LIST_NEXT(stcb, sctp_tcblist); 2131 orig--; 2132 cnt--; 2133 if (stcb == NULL) 2134 goto none_out_now; 2135 } 2136 if (stcb == NULL) 2137 goto none_out_now; 2138 2139 at = 0; 2140 ids->asls_numb_present = 0; 2141 ids->asls_more_to_get = 1; 2142 while (at < MAX_ASOC_IDS_RET) { 2143 ids->asls_assoc_id[at] = sctp_get_associd(stcb); 2144 at++; 2145 ids->asls_numb_present++; 2146 stcb = LIST_NEXT(stcb, sctp_tcblist); 2147 if (stcb == NULL) { 2148 ids->asls_more_to_get = 0; 2149 break; 2150 } 2151 } 2152 SCTP_INP_RUNLOCK(inp); 2153 } 2154 break; 2155 case SCTP_CONTEXT: 2156 { 2157 2158 struct sctp_assoc_value *av; 2159 2160 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) { 2161 error = EINVAL; 2162 break; 2163 } 2164 av = mtod(m, struct sctp_assoc_value *); 2165 if (av->assoc_id) { 2166 stcb = sctp_findassociation_ep_asocid(inp, av->assoc_id, 1); 2167 if (stcb == NULL) { 2168 error = ENOTCONN; 2169 } else { 2170 av->assoc_value = stcb->asoc.context; 2171 SCTP_TCB_UNLOCK(stcb); 2172 } 2173 } else { 2174 av->assoc_value = inp->sctp_context; 2175 } 2176 } 2177 break; 2178 case SCTP_GET_NONCE_VALUES: 2179 { 2180 struct sctp_get_nonce_values *gnv; 2181 2182 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_get_nonce_values)) { 2183 error = EINVAL; 2184 break; 2185 } 2186 gnv = mtod(m, struct sctp_get_nonce_values *); 2187 stcb = sctp_findassociation_ep_asocid(inp, gnv->gn_assoc_id, 1); 2188 if (stcb == NULL) { 2189 error = ENOTCONN; 2190 } else { 2191 gnv->gn_peers_tag = stcb->asoc.peer_vtag; 2192 gnv->gn_local_tag = stcb->asoc.my_vtag; 2193 SCTP_TCB_UNLOCK(stcb); 2194 } 2195 2196 } 2197 break; 2198 case SCTP_DELAYED_ACK_TIME: 2199 { 2200 struct sctp_assoc_value *tm; 2201 2202 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) { 2203 error = EINVAL; 2204 break; 2205 } 2206 tm = mtod(m, struct sctp_assoc_value *); 2207 2208 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2209 SCTP_INP_RLOCK(inp); 2210 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2211 if (stcb) { 2212 SCTP_TCB_LOCK(stcb); 2213 tm->assoc_value = stcb->asoc.delayed_ack; 2214 SCTP_TCB_UNLOCK(stcb); 2215 } else { 2216 tm->assoc_value = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 2217 } 2218 SCTP_INP_RUNLOCK(inp); 2219 } else { 2220 stcb = sctp_findassociation_ep_asocid(inp, tm->assoc_id, 1); 2221 if (stcb == NULL) { 2222 error = ENOTCONN; 2223 tm->assoc_value = 0; 2224 } else { 2225 stcb->asoc.delayed_ack = tm->assoc_value; 2226 SCTP_TCB_UNLOCK(stcb); 2227 } 2228 } 2229 } 2230 break; 2231 2232 case SCTP_GET_SNDBUF_USE: 2233 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_sockstat)) { 2234 error = EINVAL; 2235 } else { 2236 struct sctp_sockstat *ss; 2237 struct sctp_tcb *stcb; 2238 struct sctp_association *asoc; 2239 2240 ss = mtod(m, struct sctp_sockstat *); 2241 stcb = sctp_findassociation_ep_asocid(inp, ss->ss_assoc_id, 1); 2242 if (stcb == NULL) { 2243 error = ENOTCONN; 2244 } else { 2245 asoc = &stcb->asoc; 2246 ss->ss_total_sndbuf = (uint32_t) asoc->total_output_queue_size; 2247 ss->ss_total_recv_buf = (uint32_t) (asoc->size_on_reasm_queue + 2248 asoc->size_on_all_streams); 2249 SCTP_TCB_UNLOCK(stcb); 2250 error = 0; 2251 SCTP_BUF_LEN(m) = sizeof(struct sctp_sockstat); 2252 } 2253 } 2254 break; 2255 case SCTP_MAXBURST: 2256 { 2257 uint8_t *burst; 2258 2259 burst = mtod(m, uint8_t *); 2260 SCTP_INP_RLOCK(inp); 2261 *burst = inp->sctp_ep.max_burst; 2262 SCTP_INP_RUNLOCK(inp); 2263 SCTP_BUF_LEN(m) = sizeof(uint8_t); 2264 } 2265 break; 2266 2267 case SCTP_MAXSEG: 2268 { 2269 uint32_t *segsize; 2270 sctp_assoc_t *assoc_id; 2271 int ovh; 2272 2273 if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) { 2274 error = EINVAL; 2275 break; 2276 } 2277 if ((size_t)SCTP_BUF_LEN(m) < sizeof(sctp_assoc_t)) { 2278 error = EINVAL; 2279 break; 2280 } 2281 assoc_id = mtod(m, sctp_assoc_t *); 2282 segsize = mtod(m, uint32_t *); 2283 SCTP_BUF_LEN(m) = sizeof(uint32_t); 2284 2285 if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 2286 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) || 2287 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 2288 struct sctp_tcb *stcb; 2289 2290 SCTP_INP_RLOCK(inp); 2291 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2292 if (stcb) { 2293 SCTP_TCB_LOCK(stcb); 2294 SCTP_INP_RUNLOCK(inp); 2295 *segsize = sctp_get_frag_point(stcb, &stcb->asoc); 2296 SCTP_TCB_UNLOCK(stcb); 2297 } else { 2298 SCTP_INP_RUNLOCK(inp); 2299 goto skipit; 2300 } 2301 } else { 2302 stcb = sctp_findassociation_ep_asocid(inp, *assoc_id, 1); 2303 if (stcb) { 2304 *segsize = sctp_get_frag_point(stcb, &stcb->asoc); 2305 SCTP_TCB_UNLOCK(stcb); 2306 break; 2307 } 2308 skipit: 2309 /* 2310 * default is to get the max, if I can't 2311 * calculate from an existing association. 2312 */ 2313 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 2314 ovh = SCTP_MED_OVERHEAD; 2315 } else { 2316 ovh = SCTP_MED_V4_OVERHEAD; 2317 } 2318 *segsize = inp->sctp_frag_point - ovh; 2319 } 2320 } 2321 break; 2322 2323 case SCTP_SET_DEBUG_LEVEL: 2324 #ifdef SCTP_DEBUG 2325 { 2326 uint32_t *level; 2327 2328 if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) { 2329 error = EINVAL; 2330 break; 2331 } 2332 level = mtod(m, uint32_t *); 2333 error = 0; 2334 *level = sctp_debug_on; 2335 SCTP_BUF_LEN(m) = sizeof(uint32_t); 2336 printf("Returning DEBUG LEVEL %x is set\n", 2337 (uint32_t) sctp_debug_on); 2338 } 2339 #else /* SCTP_DEBUG */ 2340 error = EOPNOTSUPP; 2341 #endif 2342 break; 2343 case SCTP_GET_STAT_LOG: 2344 #ifdef SCTP_STAT_LOGGING 2345 error = sctp_fill_stat_log(m); 2346 #else /* SCTP_DEBUG */ 2347 error = EOPNOTSUPP; 2348 #endif 2349 break; 2350 case SCTP_EVENTS: 2351 { 2352 struct sctp_event_subscribe *events; 2353 2354 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_event_subscribe)) { 2355 error = EINVAL; 2356 break; 2357 } 2358 events = mtod(m, struct sctp_event_subscribe *); 2359 memset(events, 0, sizeof(*events)); 2360 SCTP_INP_RLOCK(inp); 2361 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT)) 2362 events->sctp_data_io_event = 1; 2363 2364 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT)) 2365 events->sctp_association_event = 1; 2366 2367 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT)) 2368 events->sctp_address_event = 1; 2369 2370 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) 2371 events->sctp_send_failure_event = 1; 2372 2373 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR)) 2374 events->sctp_peer_error_event = 1; 2375 2376 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) 2377 events->sctp_shutdown_event = 1; 2378 2379 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT)) 2380 events->sctp_partial_delivery_event = 1; 2381 2382 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) 2383 events->sctp_adaptation_layer_event = 1; 2384 2385 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT)) 2386 events->sctp_authentication_event = 1; 2387 2388 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT)) 2389 events->sctp_stream_reset_events = 1; 2390 SCTP_INP_RUNLOCK(inp); 2391 SCTP_BUF_LEN(m) = sizeof(struct sctp_event_subscribe); 2392 2393 } 2394 break; 2395 2396 case SCTP_ADAPTATION_LAYER: 2397 if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) { 2398 error = EINVAL; 2399 break; 2400 } 2401 SCTP_INP_RLOCK(inp); 2402 *mtod(m, int *)= inp->sctp_ep.adaptation_layer_indicator; 2403 SCTP_INP_RUNLOCK(inp); 2404 SCTP_BUF_LEN(m) = sizeof(int); 2405 break; 2406 case SCTP_SET_INITIAL_DBG_SEQ: 2407 if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) { 2408 error = EINVAL; 2409 break; 2410 } 2411 SCTP_INP_RLOCK(inp); 2412 *mtod(m, int *)= inp->sctp_ep.initial_sequence_debug; 2413 SCTP_INP_RUNLOCK(inp); 2414 SCTP_BUF_LEN(m) = sizeof(int); 2415 break; 2416 case SCTP_GET_LOCAL_ADDR_SIZE: 2417 if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) { 2418 error = EINVAL; 2419 break; 2420 } 2421 SCTP_INP_RLOCK(inp); 2422 *mtod(m, int *)= sctp_count_max_addresses(inp); 2423 SCTP_INP_RUNLOCK(inp); 2424 SCTP_BUF_LEN(m) = sizeof(int); 2425 break; 2426 case SCTP_GET_REMOTE_ADDR_SIZE: 2427 { 2428 sctp_assoc_t *assoc_id; 2429 uint32_t *val, sz; 2430 struct sctp_nets *net; 2431 2432 if ((size_t)SCTP_BUF_LEN(m) < sizeof(sctp_assoc_t)) { 2433 error = EINVAL; 2434 break; 2435 } 2436 stcb = NULL; 2437 val = mtod(m, uint32_t *); 2438 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2439 SCTP_INP_RLOCK(inp); 2440 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2441 if (stcb) 2442 SCTP_TCB_LOCK(stcb); 2443 SCTP_INP_RUNLOCK(inp); 2444 } 2445 if (stcb == NULL) { 2446 assoc_id = mtod(m, sctp_assoc_t *); 2447 stcb = sctp_findassociation_ep_asocid(inp, *assoc_id, 1); 2448 } 2449 if (stcb == NULL) { 2450 error = EINVAL; 2451 break; 2452 } 2453 *val = 0; 2454 sz = 0; 2455 /* Count the sizes */ 2456 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2457 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) || 2458 (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) { 2459 sz += sizeof(struct sockaddr_in6); 2460 } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) { 2461 sz += sizeof(struct sockaddr_in); 2462 } else { 2463 /* huh */ 2464 break; 2465 } 2466 } 2467 SCTP_TCB_UNLOCK(stcb); 2468 *val = sz; 2469 SCTP_BUF_LEN(m) = sizeof(uint32_t); 2470 } 2471 break; 2472 case SCTP_GET_PEER_ADDRESSES: 2473 /* 2474 * Get the address information, an array is passed in to 2475 * fill up we pack it. 2476 */ 2477 { 2478 int cpsz, left; 2479 struct sockaddr_storage *sas; 2480 struct sctp_nets *net; 2481 struct sctp_getaddresses *saddr; 2482 2483 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) { 2484 error = EINVAL; 2485 break; 2486 } 2487 left = SCTP_BUF_LEN(m) - sizeof(struct sctp_getaddresses); 2488 saddr = mtod(m, struct sctp_getaddresses *); 2489 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2490 SCTP_INP_RLOCK(inp); 2491 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2492 if (stcb) 2493 SCTP_TCB_LOCK(stcb); 2494 SCTP_INP_RUNLOCK(inp); 2495 } else 2496 stcb = sctp_findassociation_ep_asocid(inp, 2497 saddr->sget_assoc_id, 1); 2498 if (stcb == NULL) { 2499 error = ENOENT; 2500 break; 2501 } 2502 SCTP_BUF_LEN(m) = sizeof(struct sctp_getaddresses); 2503 sas = (struct sockaddr_storage *)&saddr->addr[0]; 2504 2505 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2506 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) || 2507 (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) { 2508 cpsz = sizeof(struct sockaddr_in6); 2509 } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) { 2510 cpsz = sizeof(struct sockaddr_in); 2511 } else { 2512 /* huh */ 2513 break; 2514 } 2515 if (left < cpsz) { 2516 /* not enough room. */ 2517 break; 2518 } 2519 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 2520 (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) { 2521 /* Must map the address */ 2522 in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr, 2523 (struct sockaddr_in6 *)sas); 2524 } else { 2525 memcpy(sas, &net->ro._l_addr, cpsz); 2526 } 2527 ((struct sockaddr_in *)sas)->sin_port = stcb->rport; 2528 2529 sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz); 2530 left -= cpsz; 2531 SCTP_BUF_LEN(m) += cpsz; 2532 } 2533 SCTP_TCB_UNLOCK(stcb); 2534 } 2535 break; 2536 case SCTP_GET_LOCAL_ADDRESSES: 2537 { 2538 int limit, actual; 2539 struct sockaddr_storage *sas; 2540 struct sctp_getaddresses *saddr; 2541 2542 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) { 2543 error = EINVAL; 2544 break; 2545 } 2546 saddr = mtod(m, struct sctp_getaddresses *); 2547 2548 if (saddr->sget_assoc_id) { 2549 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2550 SCTP_INP_RLOCK(inp); 2551 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2552 if (stcb) 2553 SCTP_TCB_LOCK(stcb); 2554 SCTP_INP_RUNLOCK(inp); 2555 } else 2556 stcb = sctp_findassociation_ep_asocid(inp, saddr->sget_assoc_id, 1); 2557 2558 } else { 2559 stcb = NULL; 2560 } 2561 /* 2562 * assure that the TCP model does not need a assoc 2563 * id once connected. 2564 */ 2565 if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) && 2566 (stcb == NULL)) { 2567 SCTP_INP_RLOCK(inp); 2568 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2569 if (stcb) 2570 SCTP_TCB_LOCK(stcb); 2571 SCTP_INP_RUNLOCK(inp); 2572 } 2573 sas = (struct sockaddr_storage *)&saddr->addr[0]; 2574 limit = SCTP_BUF_LEN(m) - sizeof(sctp_assoc_t); 2575 actual = sctp_fill_up_addresses(inp, stcb, limit, sas); 2576 if (stcb) 2577 SCTP_TCB_UNLOCK(stcb); 2578 SCTP_BUF_LEN(m) = sizeof(struct sockaddr_storage) + actual; 2579 } 2580 break; 2581 case SCTP_PEER_ADDR_PARAMS: 2582 { 2583 struct sctp_paddrparams *paddrp; 2584 struct sctp_nets *net; 2585 2586 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrparams)) { 2587 error = EINVAL; 2588 break; 2589 } 2590 paddrp = mtod(m, struct sctp_paddrparams *); 2591 2592 net = NULL; 2593 if (paddrp->spp_assoc_id) { 2594 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2595 SCTP_INP_RLOCK(inp); 2596 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2597 if (stcb) { 2598 SCTP_TCB_LOCK(stcb); 2599 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 2600 } 2601 SCTP_INP_RLOCK(inp); 2602 } else { 2603 stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id, 1); 2604 } 2605 if (stcb == NULL) { 2606 error = ENOENT; 2607 break; 2608 } 2609 } 2610 if ((stcb == NULL) && 2611 ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) || 2612 (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) { 2613 /* Lookup via address */ 2614 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2615 SCTP_INP_RLOCK(inp); 2616 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2617 if (stcb) { 2618 SCTP_TCB_LOCK(stcb); 2619 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 2620 } 2621 SCTP_INP_RUNLOCK(inp); 2622 } else { 2623 SCTP_INP_INCR_REF(inp); 2624 stcb = sctp_findassociation_ep_addr(&inp, 2625 (struct sockaddr *)&paddrp->spp_address, 2626 &net, NULL, NULL); 2627 if (stcb == NULL) { 2628 SCTP_INP_DECR_REF(inp); 2629 } 2630 } 2631 2632 if (stcb == NULL) { 2633 error = ENOENT; 2634 break; 2635 } 2636 } 2637 if (stcb) { 2638 /* Applys to the specific association */ 2639 paddrp->spp_flags = 0; 2640 if (net) { 2641 paddrp->spp_pathmaxrxt = net->failure_threshold; 2642 paddrp->spp_pathmtu = net->mtu; 2643 /* get flags for HB */ 2644 if (net->dest_state & SCTP_ADDR_NOHB) 2645 paddrp->spp_flags |= SPP_HB_DISABLE; 2646 else 2647 paddrp->spp_flags |= SPP_HB_ENABLE; 2648 /* get flags for PMTU */ 2649 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 2650 paddrp->spp_flags |= SPP_PMTUD_ENABLE; 2651 } else { 2652 paddrp->spp_flags |= SPP_PMTUD_DISABLE; 2653 } 2654 #ifdef AF_INET 2655 if (net->ro._l_addr.sin.sin_family == AF_INET) { 2656 paddrp->spp_ipv4_tos = net->tos_flowlabel & 0x000000fc; 2657 paddrp->spp_flags |= SPP_IPV4_TOS; 2658 } 2659 #endif 2660 #ifdef AF_INET6 2661 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) { 2662 paddrp->spp_ipv6_flowlabel = net->tos_flowlabel; 2663 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2664 } 2665 #endif 2666 } else { 2667 /* 2668 * No destination so return default 2669 * value 2670 */ 2671 paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure; 2672 paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc); 2673 #ifdef AF_INET 2674 paddrp->spp_ipv4_tos = stcb->asoc.default_tos & 0x000000fc; 2675 paddrp->spp_flags |= SPP_IPV4_TOS; 2676 #endif 2677 #ifdef AF_INET6 2678 paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel; 2679 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2680 #endif 2681 /* default settings should be these */ 2682 if (sctp_is_hb_timer_running(stcb)) { 2683 paddrp->spp_flags |= SPP_HB_ENABLE; 2684 } 2685 } 2686 paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay; 2687 paddrp->spp_sackdelay = stcb->asoc.delayed_ack; 2688 /* 2689 * Currently we don't support no sack delay 2690 * aka SPP_SACKDELAY_DISABLE. 2691 */ 2692 paddrp->spp_flags |= SPP_SACKDELAY_ENABLE; 2693 paddrp->spp_assoc_id = sctp_get_associd(stcb); 2694 SCTP_TCB_UNLOCK(stcb); 2695 } else { 2696 /* Use endpoint defaults */ 2697 SCTP_INP_RLOCK(inp); 2698 paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure; 2699 paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 2700 paddrp->spp_sackdelay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 2701 paddrp->spp_assoc_id = (sctp_assoc_t) 0; 2702 /* get inp's default */ 2703 #ifdef AF_INET 2704 paddrp->spp_ipv4_tos = inp->ip_inp.inp.inp_ip_tos; 2705 paddrp->spp_flags |= SPP_IPV4_TOS; 2706 #endif 2707 #ifdef AF_INET6 2708 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 2709 paddrp->spp_ipv6_flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo; 2710 paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 2711 } 2712 #endif 2713 /* can't return this */ 2714 paddrp->spp_pathmaxrxt = 0; 2715 paddrp->spp_pathmtu = 0; 2716 /* default behavior, no stcb */ 2717 paddrp->spp_flags = SPP_HB_ENABLE | SPP_SACKDELAY_ENABLE | SPP_PMTUD_ENABLE; 2718 2719 SCTP_INP_RUNLOCK(inp); 2720 } 2721 SCTP_BUF_LEN(m) = sizeof(struct sctp_paddrparams); 2722 } 2723 break; 2724 case SCTP_GET_PEER_ADDR_INFO: 2725 { 2726 struct sctp_paddrinfo *paddri; 2727 struct sctp_nets *net; 2728 2729 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrinfo)) { 2730 error = EINVAL; 2731 break; 2732 } 2733 paddri = mtod(m, struct sctp_paddrinfo *); 2734 net = NULL; 2735 if ((((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET) || 2736 (((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET6)) { 2737 /* Lookup via address */ 2738 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2739 SCTP_INP_RLOCK(inp); 2740 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2741 if (stcb) { 2742 SCTP_TCB_LOCK(stcb); 2743 net = sctp_findnet(stcb, 2744 (struct sockaddr *)&paddri->spinfo_address); 2745 } 2746 SCTP_INP_RUNLOCK(inp); 2747 } else { 2748 SCTP_INP_INCR_REF(inp); 2749 stcb = sctp_findassociation_ep_addr(&inp, 2750 (struct sockaddr *)&paddri->spinfo_address, 2751 &net, NULL, NULL); 2752 if (stcb == NULL) { 2753 SCTP_INP_DECR_REF(inp); 2754 } 2755 } 2756 2757 } else { 2758 stcb = NULL; 2759 } 2760 if ((stcb == NULL) || (net == NULL)) { 2761 if (stcb) { 2762 SCTP_TCB_UNLOCK(stcb); 2763 } 2764 error = ENOENT; 2765 break; 2766 } 2767 SCTP_BUF_LEN(m) = sizeof(struct sctp_paddrinfo); 2768 paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK | SCTP_ADDR_NOHB); 2769 paddri->spinfo_cwnd = net->cwnd; 2770 paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1; 2771 paddri->spinfo_rto = net->RTO; 2772 paddri->spinfo_assoc_id = sctp_get_associd(stcb); 2773 SCTP_TCB_UNLOCK(stcb); 2774 } 2775 break; 2776 case SCTP_PCB_STATUS: 2777 { 2778 struct sctp_pcbinfo *spcb; 2779 2780 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_pcbinfo)) { 2781 error = EINVAL; 2782 break; 2783 } 2784 spcb = mtod(m, struct sctp_pcbinfo *); 2785 sctp_fill_pcbinfo(spcb); 2786 SCTP_BUF_LEN(m) = sizeof(struct sctp_pcbinfo); 2787 } 2788 break; 2789 case SCTP_STATUS: 2790 { 2791 struct sctp_nets *net; 2792 struct sctp_status *sstat; 2793 2794 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_status)) { 2795 error = EINVAL; 2796 break; 2797 } 2798 sstat = mtod(m, struct sctp_status *); 2799 2800 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2801 SCTP_INP_RLOCK(inp); 2802 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2803 if (stcb) 2804 SCTP_TCB_LOCK(stcb); 2805 SCTP_INP_RUNLOCK(inp); 2806 } else 2807 stcb = sctp_findassociation_ep_asocid(inp, sstat->sstat_assoc_id, 1); 2808 2809 if (stcb == NULL) { 2810 error = EINVAL; 2811 break; 2812 } 2813 /* 2814 * I think passing the state is fine since 2815 * sctp_constants.h will be available to the user 2816 * land. 2817 */ 2818 sstat->sstat_state = stcb->asoc.state; 2819 sstat->sstat_rwnd = stcb->asoc.peers_rwnd; 2820 sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt; 2821 /* 2822 * We can't include chunks that have been passed to 2823 * the socket layer. Only things in queue. 2824 */ 2825 sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue + 2826 stcb->asoc.cnt_on_all_streams); 2827 2828 2829 sstat->sstat_instrms = stcb->asoc.streamincnt; 2830 sstat->sstat_outstrms = stcb->asoc.streamoutcnt; 2831 sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc); 2832 memcpy(&sstat->sstat_primary.spinfo_address, 2833 &stcb->asoc.primary_destination->ro._l_addr, 2834 ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len); 2835 net = stcb->asoc.primary_destination; 2836 ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport; 2837 /* 2838 * Again the user can get info from sctp_constants.h 2839 * for what the state of the network is. 2840 */ 2841 sstat->sstat_primary.spinfo_state = net->dest_state & SCTP_REACHABLE_MASK; 2842 sstat->sstat_primary.spinfo_cwnd = net->cwnd; 2843 sstat->sstat_primary.spinfo_srtt = net->lastsa; 2844 sstat->sstat_primary.spinfo_rto = net->RTO; 2845 sstat->sstat_primary.spinfo_mtu = net->mtu; 2846 sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb); 2847 SCTP_TCB_UNLOCK(stcb); 2848 SCTP_BUF_LEN(m) = sizeof(*sstat); 2849 } 2850 break; 2851 case SCTP_RTOINFO: 2852 { 2853 struct sctp_rtoinfo *srto; 2854 2855 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_rtoinfo)) { 2856 error = EINVAL; 2857 break; 2858 } 2859 srto = mtod(m, struct sctp_rtoinfo *); 2860 if (srto->srto_assoc_id == 0) { 2861 /* Endpoint only please */ 2862 SCTP_INP_RLOCK(inp); 2863 srto->srto_initial = inp->sctp_ep.initial_rto; 2864 srto->srto_max = inp->sctp_ep.sctp_maxrto; 2865 srto->srto_min = inp->sctp_ep.sctp_minrto; 2866 SCTP_INP_RUNLOCK(inp); 2867 break; 2868 } 2869 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2870 SCTP_INP_RLOCK(inp); 2871 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2872 if (stcb) 2873 SCTP_TCB_LOCK(stcb); 2874 SCTP_INP_RUNLOCK(inp); 2875 } else 2876 stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id, 1); 2877 2878 if (stcb == NULL) { 2879 error = EINVAL; 2880 break; 2881 } 2882 srto->srto_initial = stcb->asoc.initial_rto; 2883 srto->srto_max = stcb->asoc.maxrto; 2884 srto->srto_min = stcb->asoc.minrto; 2885 SCTP_TCB_UNLOCK(stcb); 2886 SCTP_BUF_LEN(m) = sizeof(*srto); 2887 } 2888 break; 2889 case SCTP_ASSOCINFO: 2890 { 2891 struct sctp_assocparams *sasoc; 2892 2893 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assocparams)) { 2894 error = EINVAL; 2895 break; 2896 } 2897 sasoc = mtod(m, struct sctp_assocparams *); 2898 stcb = NULL; 2899 2900 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2901 SCTP_INP_RLOCK(inp); 2902 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2903 if (stcb) { 2904 2905 SCTP_TCB_LOCK(stcb); 2906 } 2907 SCTP_INP_RUNLOCK(inp); 2908 } else if (sasoc->sasoc_assoc_id) { 2909 stcb = sctp_findassociation_ep_asocid(inp, 2910 sasoc->sasoc_assoc_id, 1); 2911 if (stcb == NULL) { 2912 error = ENOENT; 2913 break; 2914 } 2915 } else { 2916 stcb = NULL; 2917 } 2918 if (stcb) { 2919 sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times; 2920 sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets; 2921 sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd; 2922 sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd; 2923 sasoc->sasoc_cookie_life = stcb->asoc.cookie_life; 2924 SCTP_TCB_UNLOCK(stcb); 2925 } else { 2926 SCTP_INP_RLOCK(inp); 2927 sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times; 2928 sasoc->sasoc_number_peer_destinations = 0; 2929 sasoc->sasoc_peer_rwnd = 0; 2930 sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv); 2931 sasoc->sasoc_cookie_life = inp->sctp_ep.def_cookie_life; 2932 SCTP_INP_RUNLOCK(inp); 2933 } 2934 SCTP_BUF_LEN(m) = sizeof(*sasoc); 2935 } 2936 break; 2937 case SCTP_DEFAULT_SEND_PARAM: 2938 { 2939 struct sctp_sndrcvinfo *s_info; 2940 2941 if (SCTP_BUF_LEN(m) != sizeof(struct sctp_sndrcvinfo)) { 2942 error = EINVAL; 2943 break; 2944 } 2945 s_info = mtod(m, struct sctp_sndrcvinfo *); 2946 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2947 SCTP_INP_RLOCK(inp); 2948 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2949 if (stcb) 2950 SCTP_TCB_LOCK(stcb); 2951 SCTP_INP_RUNLOCK(inp); 2952 } else 2953 stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id, 1); 2954 2955 if (stcb == NULL) { 2956 error = ENOENT; 2957 break; 2958 } 2959 /* Copy it out */ 2960 *s_info = stcb->asoc.def_send; 2961 SCTP_TCB_UNLOCK(stcb); 2962 SCTP_BUF_LEN(m) = sizeof(*s_info); 2963 } 2964 break; 2965 case SCTP_INITMSG: 2966 { 2967 struct sctp_initmsg *sinit; 2968 2969 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_initmsg)) { 2970 error = EINVAL; 2971 break; 2972 } 2973 sinit = mtod(m, struct sctp_initmsg *); 2974 SCTP_INP_RLOCK(inp); 2975 sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count; 2976 sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome; 2977 sinit->sinit_max_attempts = inp->sctp_ep.max_init_times; 2978 sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max; 2979 SCTP_INP_RUNLOCK(inp); 2980 SCTP_BUF_LEN(m) = sizeof(*sinit); 2981 } 2982 break; 2983 case SCTP_PRIMARY_ADDR: 2984 /* we allow a "get" operation on this */ 2985 { 2986 struct sctp_setprim *ssp; 2987 2988 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setprim)) { 2989 error = EINVAL; 2990 break; 2991 } 2992 ssp = mtod(m, struct sctp_setprim *); 2993 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 2994 SCTP_INP_RLOCK(inp); 2995 stcb = LIST_FIRST(&inp->sctp_asoc_list); 2996 if (stcb) 2997 SCTP_TCB_LOCK(stcb); 2998 SCTP_INP_RUNLOCK(inp); 2999 } else { 3000 stcb = sctp_findassociation_ep_asocid(inp, ssp->ssp_assoc_id, 1); 3001 if (stcb == NULL) { 3002 /* 3003 * one last shot, try it by the 3004 * address in 3005 */ 3006 struct sctp_nets *net; 3007 3008 SCTP_INP_INCR_REF(inp); 3009 stcb = sctp_findassociation_ep_addr(&inp, 3010 (struct sockaddr *)&ssp->ssp_addr, 3011 &net, NULL, NULL); 3012 if (stcb == NULL) { 3013 SCTP_INP_DECR_REF(inp); 3014 } 3015 } 3016 if (stcb == NULL) { 3017 error = EINVAL; 3018 break; 3019 } 3020 } 3021 /* simply copy out the sockaddr_storage... */ 3022 memcpy(&ssp->ssp_addr, 3023 &stcb->asoc.primary_destination->ro._l_addr, 3024 ((struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr)->sa_len); 3025 SCTP_TCB_UNLOCK(stcb); 3026 SCTP_BUF_LEN(m) = sizeof(*ssp); 3027 } 3028 break; 3029 3030 case SCTP_HMAC_IDENT: 3031 { 3032 struct sctp_hmacalgo *shmac; 3033 sctp_hmaclist_t *hmaclist; 3034 uint32_t size; 3035 int i; 3036 3037 if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*shmac)) { 3038 error = EINVAL; 3039 break; 3040 } 3041 shmac = mtod(m, struct sctp_hmacalgo *); 3042 SCTP_INP_RLOCK(inp); 3043 hmaclist = inp->sctp_ep.local_hmacs; 3044 if (hmaclist == NULL) { 3045 /* no HMACs to return */ 3046 SCTP_BUF_LEN(m) = sizeof(*shmac); 3047 break; 3048 } 3049 /* is there room for all of the hmac ids? */ 3050 size = sizeof(*shmac) + (hmaclist->num_algo * 3051 sizeof(shmac->shmac_idents[0])); 3052 if ((size_t)(SCTP_BUF_LEN(m)) < size) { 3053 error = EINVAL; 3054 SCTP_INP_RUNLOCK(inp); 3055 break; 3056 } 3057 /* copy in the list */ 3058 for (i = 0; i < hmaclist->num_algo; i++) 3059 shmac->shmac_idents[i] = hmaclist->hmac[i]; 3060 SCTP_INP_RUNLOCK(inp); 3061 SCTP_BUF_LEN(m) = size; 3062 break; 3063 } 3064 case SCTP_AUTH_ACTIVE_KEY: 3065 { 3066 struct sctp_authkeyid *scact; 3067 3068 if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*scact)) { 3069 error = EINVAL; 3070 break; 3071 } 3072 scact = mtod(m, struct sctp_authkeyid *); 3073 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3074 /* 3075 * if one-to-one, get from the connected 3076 * assoc; else endpoint 3077 */ 3078 SCTP_INP_RLOCK(inp); 3079 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3080 if (stcb) 3081 SCTP_TCB_LOCK(stcb); 3082 SCTP_INP_RUNLOCK(inp); 3083 } else if (scact->scact_assoc_id) { 3084 stcb = sctp_findassociation_ep_asocid(inp, scact->scact_assoc_id, 1); 3085 if (stcb == NULL) { 3086 error = ENOENT; 3087 break; 3088 } 3089 } 3090 if (stcb != NULL) { 3091 /* get the active key on the assoc */ 3092 scact->scact_keynumber = stcb->asoc.authinfo.assoc_keyid; 3093 SCTP_TCB_UNLOCK(stcb); 3094 } else { 3095 /* get the endpoint active key */ 3096 SCTP_INP_RLOCK(inp); 3097 scact->scact_keynumber = inp->sctp_ep.default_keyid; 3098 SCTP_INP_RUNLOCK(inp); 3099 } 3100 SCTP_BUF_LEN(m) = sizeof(*scact); 3101 break; 3102 } 3103 case SCTP_LOCAL_AUTH_CHUNKS: 3104 { 3105 struct sctp_authchunks *sac; 3106 sctp_auth_chklist_t *chklist = NULL; 3107 int size = 0; 3108 3109 if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*sac)) { 3110 error = EINVAL; 3111 break; 3112 } 3113 sac = mtod(m, struct sctp_authchunks *); 3114 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3115 /* 3116 * if one-to-one, get from the connected 3117 * assoc; else endpoint 3118 */ 3119 SCTP_INP_RLOCK(inp); 3120 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3121 if (stcb != NULL) 3122 SCTP_TCB_LOCK(stcb); 3123 SCTP_INP_RUNLOCK(inp); 3124 } else if (sac->gauth_assoc_id) { 3125 stcb = sctp_findassociation_ep_asocid(inp, sac->gauth_assoc_id, 1); 3126 if (stcb == NULL) { 3127 error = ENOENT; 3128 break; 3129 } 3130 } 3131 if (stcb != NULL) { 3132 /* get off the assoc */ 3133 chklist = stcb->asoc.local_auth_chunks; 3134 if (chklist == NULL) { 3135 error = EINVAL; 3136 SCTP_TCB_UNLOCK(stcb); 3137 break; 3138 } 3139 /* is there enough space? */ 3140 size = sctp_auth_get_chklist_size(chklist); 3141 if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) { 3142 error = EINVAL; 3143 SCTP_TCB_UNLOCK(stcb); 3144 break; 3145 } 3146 /* copy in the chunks */ 3147 sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 3148 SCTP_TCB_UNLOCK(stcb); 3149 } else { 3150 /* get off the endpoint */ 3151 SCTP_INP_RLOCK(inp); 3152 chklist = inp->sctp_ep.local_auth_chunks; 3153 if (chklist == NULL) { 3154 error = EINVAL; 3155 SCTP_INP_RUNLOCK(inp); 3156 break; 3157 } 3158 /* is there enough space? */ 3159 size = sctp_auth_get_chklist_size(chklist); 3160 if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) { 3161 error = EINVAL; 3162 SCTP_INP_RUNLOCK(inp); 3163 break; 3164 } 3165 /* copy in the chunks */ 3166 sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 3167 SCTP_INP_RUNLOCK(inp); 3168 } 3169 SCTP_BUF_LEN(m) = sizeof(struct sctp_authchunks) + size; 3170 break; 3171 } 3172 case SCTP_PEER_AUTH_CHUNKS: 3173 { 3174 struct sctp_authchunks *sac; 3175 sctp_auth_chklist_t *chklist = NULL; 3176 int size = 0; 3177 3178 if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*sac)) { 3179 error = EINVAL; 3180 break; 3181 } 3182 sac = mtod(m, struct sctp_authchunks *); 3183 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3184 /* 3185 * if one-to-one, get from the connected 3186 * assoc, else endpoint 3187 */ 3188 SCTP_INP_RLOCK(inp); 3189 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3190 if (stcb != NULL) 3191 SCTP_TCB_LOCK(stcb); 3192 SCTP_INP_RUNLOCK(inp); 3193 } else if (sac->gauth_assoc_id) { 3194 stcb = sctp_findassociation_ep_asocid(inp, sac->gauth_assoc_id, 1); 3195 } 3196 if (stcb == NULL) { 3197 error = ENOENT; 3198 break; 3199 } 3200 /* get off the assoc */ 3201 chklist = stcb->asoc.peer_auth_chunks; 3202 if (chklist == NULL) { 3203 error = EINVAL; 3204 SCTP_TCB_UNLOCK(stcb); 3205 break; 3206 } 3207 /* is there enough space? */ 3208 size = sctp_auth_get_chklist_size(chklist); 3209 if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) { 3210 error = EINVAL; 3211 SCTP_TCB_UNLOCK(stcb); 3212 break; 3213 } 3214 /* copy in the chunks */ 3215 sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 3216 SCTP_TCB_UNLOCK(stcb); 3217 SCTP_BUF_LEN(m) = sizeof(struct sctp_authchunks) + size; 3218 break; 3219 } 3220 3221 3222 default: 3223 error = ENOPROTOOPT; 3224 SCTP_BUF_LEN(m) = 0; 3225 break; 3226 } /* end switch (sopt->sopt_name) */ 3227 return (error); 3228 } 3229 3230 3231 static int 3232 sctp_optsset(struct socket *so, 3233 int opt, 3234 struct mbuf **mp, 3235 struct thread *p 3236 ) 3237 { 3238 int error, *mopt, set_opt, s; 3239 struct mbuf *m; 3240 struct sctp_tcb *stcb = NULL; 3241 struct sctp_inpcb *inp; 3242 3243 if (mp == NULL) { 3244 return (EINVAL); 3245 } 3246 m = *mp; 3247 if (m == NULL) 3248 return (EINVAL); 3249 3250 inp = (struct sctp_inpcb *)so->so_pcb; 3251 if (inp == 0) 3252 return EINVAL; 3253 3254 error = 0; 3255 switch (opt) { 3256 case SCTP_NODELAY: 3257 case SCTP_AUTOCLOSE: 3258 case SCTP_AUTO_ASCONF: 3259 case SCTP_EXPLICIT_EOR: 3260 case SCTP_DISABLE_FRAGMENTS: 3261 case SCTP_USE_EXT_RCVINFO: 3262 case SCTP_I_WANT_MAPPED_V4_ADDR: 3263 /* copy in the option value */ 3264 if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) { 3265 error = EINVAL; 3266 break; 3267 } 3268 mopt = mtod(m, int *); 3269 set_opt = 0; 3270 if (error) 3271 break; 3272 switch (opt) { 3273 case SCTP_DISABLE_FRAGMENTS: 3274 set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT; 3275 break; 3276 case SCTP_AUTO_ASCONF: 3277 set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF; 3278 break; 3279 case SCTP_EXPLICIT_EOR: 3280 set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR; 3281 break; 3282 case SCTP_USE_EXT_RCVINFO: 3283 set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO; 3284 break; 3285 case SCTP_I_WANT_MAPPED_V4_ADDR: 3286 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 3287 set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4; 3288 } else { 3289 return (EINVAL); 3290 } 3291 break; 3292 case SCTP_NODELAY: 3293 set_opt = SCTP_PCB_FLAGS_NODELAY; 3294 break; 3295 case SCTP_AUTOCLOSE: 3296 set_opt = SCTP_PCB_FLAGS_AUTOCLOSE; 3297 /* 3298 * The value is in ticks. Note this does not effect 3299 * old associations, only new ones. 3300 */ 3301 inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt); 3302 break; 3303 } 3304 SCTP_INP_WLOCK(inp); 3305 if (*mopt != 0) { 3306 sctp_feature_on(inp, set_opt); 3307 } else { 3308 sctp_feature_off(inp, set_opt); 3309 } 3310 SCTP_INP_WUNLOCK(inp); 3311 break; 3312 case SCTP_PARTIAL_DELIVERY_POINT: 3313 { 3314 if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) { 3315 error = EINVAL; 3316 break; 3317 } 3318 inp->partial_delivery_point = *mtod(m, unsigned int *); 3319 SCTP_BUF_LEN(m) = sizeof(unsigned int); 3320 } 3321 break; 3322 case SCTP_FRAGMENT_INTERLEAVE: 3323 /* not yet until we re-write sctp_recvmsg() */ 3324 { 3325 int on_off; 3326 3327 if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) { 3328 error = EINVAL; 3329 break; 3330 } 3331 on_off = *(mtod(m, int *)); 3332 if (on_off) { 3333 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 3334 } else { 3335 sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 3336 } 3337 } 3338 break; 3339 case SCTP_CMT_ON_OFF: 3340 { 3341 struct sctp_assoc_value *av; 3342 3343 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) { 3344 error = EINVAL; 3345 break; 3346 } 3347 av = mtod(m, struct sctp_assoc_value *); 3348 stcb = sctp_findassociation_ep_asocid(inp, av->assoc_id, 1); 3349 if (stcb == NULL) { 3350 error = ENOTCONN; 3351 } else { 3352 if (sctp_cmt_on_off) { 3353 stcb->asoc.sctp_cmt_on_off = (uint8_t) av->assoc_value; 3354 } else { 3355 if ((stcb->asoc.sctp_cmt_on_off) && (av->assoc_value == 0)) { 3356 stcb->asoc.sctp_cmt_on_off = 0; 3357 } else { 3358 error = EACCES; 3359 } 3360 } 3361 SCTP_TCB_UNLOCK(stcb); 3362 } 3363 } 3364 break; 3365 case SCTP_CMT_USE_DAC: 3366 { 3367 if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) { 3368 error = EINVAL; 3369 break; 3370 } 3371 sctp_cmt_sockopt_use_dac = *mtod(m, unsigned int *); 3372 if (sctp_cmt_sockopt_use_dac != 0) 3373 sctp_cmt_sockopt_use_dac = 1; 3374 } 3375 break; 3376 case SCTP_CLR_STAT_LOG: 3377 #ifdef SCTP_STAT_LOGGING 3378 sctp_clr_stat_log(); 3379 #else 3380 error = EOPNOTSUPP; 3381 #endif 3382 break; 3383 case SCTP_CONTEXT: 3384 { 3385 3386 struct sctp_assoc_value *av; 3387 3388 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) { 3389 error = EINVAL; 3390 break; 3391 } 3392 av = mtod(m, struct sctp_assoc_value *); 3393 if (av->assoc_id) { 3394 stcb = sctp_findassociation_ep_asocid(inp, av->assoc_id, 1); 3395 if (stcb == NULL) { 3396 error = ENOTCONN; 3397 } else { 3398 stcb->asoc.context = av->assoc_value; 3399 SCTP_TCB_UNLOCK(stcb); 3400 } 3401 } else { 3402 inp->sctp_context = av->assoc_value; 3403 } 3404 } 3405 break; 3406 case SCTP_DELAYED_ACK_TIME: 3407 { 3408 struct sctp_assoc_value *tm; 3409 3410 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) { 3411 error = EINVAL; 3412 break; 3413 } 3414 tm = mtod(m, struct sctp_assoc_value *); 3415 3416 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3417 SCTP_INP_WLOCK(inp); 3418 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3419 if (stcb) { 3420 SCTP_TCB_LOCK(stcb); 3421 stcb->asoc.delayed_ack = tm->assoc_value; 3422 SCTP_TCB_UNLOCK(stcb); 3423 } else { 3424 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(tm->assoc_value); 3425 } 3426 SCTP_INP_WUNLOCK(inp); 3427 } else { 3428 if (tm->assoc_id) { 3429 stcb = sctp_findassociation_ep_asocid(inp, tm->assoc_id, 1); 3430 if (stcb == NULL) { 3431 error = ENOTCONN; 3432 } else { 3433 stcb->asoc.delayed_ack = tm->assoc_value; 3434 SCTP_TCB_UNLOCK(stcb); 3435 } 3436 } else { 3437 SCTP_INP_WLOCK(inp); 3438 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(tm->assoc_value); 3439 SCTP_INP_WUNLOCK(inp); 3440 } 3441 } 3442 } 3443 break; 3444 3445 case SCTP_AUTH_CHUNK: 3446 { 3447 struct sctp_authchunk *sauth; 3448 3449 if ((size_t)SCTP_BUF_LEN(m) < sizeof(*sauth)) { 3450 error = EINVAL; 3451 break; 3452 } 3453 sauth = mtod(m, struct sctp_authchunk *); 3454 if (sctp_auth_add_chunk(sauth->sauth_chunk, 3455 inp->sctp_ep.local_auth_chunks)) 3456 error = EINVAL; 3457 break; 3458 } 3459 case SCTP_AUTH_KEY: 3460 { 3461 struct sctp_authkey *sca; 3462 struct sctp_keyhead *shared_keys; 3463 sctp_sharedkey_t *shared_key; 3464 sctp_key_t *key = NULL; 3465 int size; 3466 3467 size = SCTP_BUF_LEN(m) - sizeof(*sca); 3468 if (size < 0) { 3469 error = EINVAL; 3470 break; 3471 } 3472 sca = mtod(m, struct sctp_authkey *); 3473 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3474 /* 3475 * if one-to-one, set it on the connected 3476 * assoc; else endpoint 3477 */ 3478 SCTP_INP_RLOCK(inp); 3479 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3480 if (stcb) 3481 SCTP_TCB_LOCK(stcb); 3482 SCTP_INP_RUNLOCK(inp); 3483 } else if (sca->sca_assoc_id) { 3484 stcb = sctp_findassociation_ep_asocid(inp, sca->sca_assoc_id, 1); 3485 if (stcb == NULL) { 3486 error = ENOENT; 3487 break; 3488 } 3489 } 3490 if (stcb != NULL) { 3491 /* set it on the assoc */ 3492 shared_keys = &stcb->asoc.shared_keys; 3493 /* clear the cached keys for this key id */ 3494 sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 3495 /* 3496 * create the new shared key and 3497 * insert/replace it 3498 */ 3499 if (size > 0) { 3500 key = sctp_set_key(sca->sca_key, (uint32_t) size); 3501 if (key == NULL) { 3502 error = ENOMEM; 3503 SCTP_TCB_UNLOCK(stcb); 3504 break; 3505 } 3506 } 3507 shared_key = sctp_alloc_sharedkey(); 3508 if (shared_key == NULL) { 3509 sctp_free_key(key); 3510 error = ENOMEM; 3511 SCTP_TCB_UNLOCK(stcb); 3512 break; 3513 } 3514 shared_key->key = key; 3515 shared_key->keyid = sca->sca_keynumber; 3516 sctp_insert_sharedkey(shared_keys, shared_key); 3517 SCTP_TCB_UNLOCK(stcb); 3518 } else { 3519 /* ste it on the endpoint */ 3520 SCTP_INP_WLOCK(inp); 3521 shared_keys = &inp->sctp_ep.shared_keys; 3522 /* 3523 * clear the cached keys on all assocs for 3524 * this key id 3525 */ 3526 sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber); 3527 /* 3528 * create the new shared key and 3529 * insert/replace it 3530 */ 3531 if (size > 0) { 3532 key = sctp_set_key(sca->sca_key, (uint32_t) size); 3533 if (key == NULL) { 3534 error = ENOMEM; 3535 SCTP_INP_WUNLOCK(inp); 3536 break; 3537 } 3538 } 3539 shared_key = sctp_alloc_sharedkey(); 3540 if (shared_key == NULL) { 3541 sctp_free_key(key); 3542 error = ENOMEM; 3543 SCTP_INP_WUNLOCK(inp); 3544 break; 3545 } 3546 shared_key->key = key; 3547 shared_key->keyid = sca->sca_keynumber; 3548 sctp_insert_sharedkey(shared_keys, shared_key); 3549 SCTP_INP_WUNLOCK(inp); 3550 } 3551 break; 3552 } 3553 case SCTP_HMAC_IDENT: 3554 { 3555 struct sctp_hmacalgo *shmac; 3556 sctp_hmaclist_t *hmaclist; 3557 uint32_t hmacid; 3558 int size, i; 3559 3560 size = SCTP_BUF_LEN(m) - sizeof(*shmac); 3561 if (size < 0) { 3562 error = EINVAL; 3563 break; 3564 } 3565 shmac = mtod(m, struct sctp_hmacalgo *); 3566 size = size / sizeof(shmac->shmac_idents[0]); 3567 hmaclist = sctp_alloc_hmaclist(size); 3568 if (hmaclist == NULL) { 3569 error = ENOMEM; 3570 break; 3571 } 3572 for (i = 0; i < size; i++) { 3573 hmacid = shmac->shmac_idents[i]; 3574 if (sctp_auth_add_hmacid(hmaclist, (uint16_t) hmacid)) { 3575 /* invalid HMACs were found */ ; 3576 error = EINVAL; 3577 sctp_free_hmaclist(hmaclist); 3578 goto sctp_set_hmac_done; 3579 } 3580 } 3581 /* set it on the endpoint */ 3582 SCTP_INP_WLOCK(inp); 3583 if (inp->sctp_ep.local_hmacs) 3584 sctp_free_hmaclist(inp->sctp_ep.local_hmacs); 3585 inp->sctp_ep.local_hmacs = hmaclist; 3586 SCTP_INP_WUNLOCK(inp); 3587 sctp_set_hmac_done: 3588 break; 3589 } 3590 case SCTP_AUTH_ACTIVE_KEY: 3591 { 3592 struct sctp_authkeyid *scact; 3593 3594 if ((size_t)SCTP_BUF_LEN(m) < sizeof(*scact)) { 3595 error = EINVAL; 3596 break; 3597 } 3598 scact = mtod(m, struct sctp_authkeyid *); 3599 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3600 /* 3601 * if one-to-one, set it on the connected 3602 * assoc; else endpoint 3603 */ 3604 SCTP_INP_RLOCK(inp); 3605 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3606 if (stcb) 3607 SCTP_TCB_LOCK(stcb); 3608 SCTP_INP_RUNLOCK(inp); 3609 } else if (scact->scact_assoc_id) { 3610 stcb = sctp_findassociation_ep_asocid(inp, scact->scact_assoc_id, 1); 3611 if (stcb == NULL) { 3612 error = ENOENT; 3613 break; 3614 } 3615 } 3616 /* set the active key on the right place */ 3617 if (stcb != NULL) { 3618 /* set the active key on the assoc */ 3619 if (sctp_auth_setactivekey(stcb, scact->scact_keynumber)) 3620 error = EINVAL; 3621 SCTP_TCB_UNLOCK(stcb); 3622 } else { 3623 /* set the active key on the endpoint */ 3624 SCTP_INP_WLOCK(inp); 3625 if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber)) 3626 error = EINVAL; 3627 SCTP_INP_WUNLOCK(inp); 3628 } 3629 break; 3630 } 3631 case SCTP_AUTH_DELETE_KEY: 3632 { 3633 struct sctp_authkeyid *scdel; 3634 3635 if ((size_t)SCTP_BUF_LEN(m) < sizeof(*scdel)) { 3636 error = EINVAL; 3637 break; 3638 } 3639 scdel = mtod(m, struct sctp_authkeyid *); 3640 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3641 /* 3642 * if one-to-one, delete from the connected 3643 * assoc; else endpoint 3644 */ 3645 SCTP_INP_RLOCK(inp); 3646 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3647 if (stcb) 3648 SCTP_TCB_LOCK(stcb); 3649 SCTP_INP_RUNLOCK(inp); 3650 } else if (scdel->scact_assoc_id) { 3651 stcb = sctp_findassociation_ep_asocid(inp, scdel->scact_assoc_id, 1); 3652 if (stcb == NULL) { 3653 error = ENOENT; 3654 break; 3655 } 3656 } 3657 /* delete the key from the right place */ 3658 if (stcb != NULL) { 3659 if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber)) 3660 error = EINVAL; 3661 SCTP_TCB_UNLOCK(stcb); 3662 } else { 3663 SCTP_INP_WLOCK(inp); 3664 if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber)) 3665 error = EINVAL; 3666 SCTP_INP_WUNLOCK(inp); 3667 } 3668 break; 3669 } 3670 3671 case SCTP_RESET_STREAMS: 3672 { 3673 struct sctp_stream_reset *strrst; 3674 uint8_t send_in = 0, send_tsn = 0, send_out = 0; 3675 int i; 3676 3677 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_stream_reset)) { 3678 error = EINVAL; 3679 break; 3680 } 3681 strrst = mtod(m, struct sctp_stream_reset *); 3682 3683 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3684 SCTP_INP_RLOCK(inp); 3685 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3686 if (stcb) 3687 SCTP_TCB_LOCK(stcb); 3688 SCTP_INP_RUNLOCK(inp); 3689 } else 3690 stcb = sctp_findassociation_ep_asocid(inp, strrst->strrst_assoc_id, 1); 3691 if (stcb == NULL) { 3692 error = ENOENT; 3693 break; 3694 } 3695 if (stcb->asoc.peer_supports_strreset == 0) { 3696 /* 3697 * Peer does not support it, we return 3698 * protocol not supported since this is true 3699 * for this feature and this peer, not the 3700 * socket request in general. 3701 */ 3702 error = EPROTONOSUPPORT; 3703 SCTP_TCB_UNLOCK(stcb); 3704 break; 3705 } 3706 if (stcb->asoc.stream_reset_outstanding) { 3707 error = EALREADY; 3708 SCTP_TCB_UNLOCK(stcb); 3709 break; 3710 } 3711 if (strrst->strrst_flags == SCTP_RESET_LOCAL_RECV) { 3712 send_in = 1; 3713 } else if (strrst->strrst_flags == SCTP_RESET_LOCAL_SEND) { 3714 send_out = 1; 3715 } else if (strrst->strrst_flags == SCTP_RESET_BOTH) { 3716 send_in = 1; 3717 send_out = 1; 3718 } else if (strrst->strrst_flags == SCTP_RESET_TSN) { 3719 send_tsn = 1; 3720 } else { 3721 error = EINVAL; 3722 SCTP_TCB_UNLOCK(stcb); 3723 break; 3724 } 3725 for (i = 0; i < strrst->strrst_num_streams; i++) { 3726 if ((send_in) && 3727 3728 (strrst->strrst_list[i] > stcb->asoc.streamincnt)) { 3729 error = EINVAL; 3730 goto get_out; 3731 } 3732 if ((send_out) && 3733 (strrst->strrst_list[i] > stcb->asoc.streamoutcnt)) { 3734 error = EINVAL; 3735 goto get_out; 3736 } 3737 } 3738 if (error) { 3739 get_out: 3740 SCTP_TCB_UNLOCK(stcb); 3741 break; 3742 } 3743 error = sctp_send_str_reset_req(stcb, strrst->strrst_num_streams, 3744 strrst->strrst_list, 3745 send_out, (stcb->asoc.str_reset_seq_in - 3), 3746 send_in, send_tsn); 3747 3748 s = splnet(); 3749 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ); 3750 SCTP_TCB_UNLOCK(stcb); 3751 splx(s); 3752 3753 } 3754 break; 3755 case SCTP_CONNECT_X: 3756 if ((size_t)SCTP_BUF_LEN(m) < (sizeof(int) + sizeof(struct sockaddr_in))) { 3757 error = EINVAL; 3758 break; 3759 } 3760 error = sctp_do_connect_x(so, inp, m, p, 0); 3761 break; 3762 3763 case SCTP_CONNECT_X_DELAYED: 3764 if ((size_t)SCTP_BUF_LEN(m) < (sizeof(int) + sizeof(struct sockaddr_in))) { 3765 error = EINVAL; 3766 break; 3767 } 3768 error = sctp_do_connect_x(so, inp, m, p, 1); 3769 break; 3770 3771 case SCTP_CONNECT_X_COMPLETE: 3772 { 3773 struct sockaddr *sa; 3774 struct sctp_nets *net; 3775 3776 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sockaddr_in)) { 3777 error = EINVAL; 3778 break; 3779 } 3780 sa = mtod(m, struct sockaddr *); 3781 /* find tcb */ 3782 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3783 SCTP_INP_RLOCK(inp); 3784 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3785 if (stcb) { 3786 SCTP_TCB_LOCK(stcb); 3787 net = sctp_findnet(stcb, sa); 3788 } 3789 SCTP_INP_RUNLOCK(inp); 3790 } else { 3791 SCTP_INP_INCR_REF(inp); 3792 stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL); 3793 if (stcb == NULL) { 3794 SCTP_INP_DECR_REF(inp); 3795 } 3796 } 3797 3798 if (stcb == NULL) { 3799 error = ENOENT; 3800 break; 3801 } 3802 if (stcb->asoc.delayed_connection == 1) { 3803 stcb->asoc.delayed_connection = 0; 3804 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 3805 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, 3806 stcb->asoc.primary_destination, 3807 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9); 3808 sctp_send_initiate(inp, stcb); 3809 } else { 3810 /* 3811 * already expired or did not use delayed 3812 * connectx 3813 */ 3814 error = EALREADY; 3815 } 3816 SCTP_TCB_UNLOCK(stcb); 3817 } 3818 break; 3819 case SCTP_MAXBURST: 3820 { 3821 uint8_t *burst; 3822 3823 SCTP_INP_WLOCK(inp); 3824 burst = mtod(m, uint8_t *); 3825 if (*burst) { 3826 inp->sctp_ep.max_burst = *burst; 3827 } 3828 SCTP_INP_WUNLOCK(inp); 3829 } 3830 break; 3831 case SCTP_MAXSEG: 3832 { 3833 uint32_t *segsize; 3834 int ovh; 3835 3836 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 3837 ovh = SCTP_MED_OVERHEAD; 3838 } else { 3839 ovh = SCTP_MED_V4_OVERHEAD; 3840 } 3841 segsize = mtod(m, uint32_t *); 3842 if (*segsize < 1) { 3843 error = EINVAL; 3844 break; 3845 } 3846 SCTP_INP_WLOCK(inp); 3847 inp->sctp_frag_point = (*segsize + ovh); 3848 if (inp->sctp_frag_point < MHLEN) { 3849 inp->sctp_frag_point = MHLEN; 3850 } 3851 SCTP_INP_WUNLOCK(inp); 3852 } 3853 break; 3854 case SCTP_SET_DEBUG_LEVEL: 3855 #ifdef SCTP_DEBUG 3856 { 3857 uint32_t *level; 3858 3859 if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) { 3860 error = EINVAL; 3861 break; 3862 } 3863 level = mtod(m, uint32_t *); 3864 error = 0; 3865 sctp_debug_on = (*level & (SCTP_DEBUG_ALL | 3866 SCTP_DEBUG_NOISY)); 3867 printf("SETTING DEBUG LEVEL to %x\n", 3868 (uint32_t) sctp_debug_on); 3869 3870 } 3871 #else 3872 error = EOPNOTSUPP; 3873 #endif /* SCTP_DEBUG */ 3874 break; 3875 case SCTP_EVENTS: 3876 { 3877 struct sctp_event_subscribe *events; 3878 3879 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_event_subscribe)) { 3880 error = EINVAL; 3881 break; 3882 } 3883 SCTP_INP_WLOCK(inp); 3884 events = mtod(m, struct sctp_event_subscribe *); 3885 if (events->sctp_data_io_event) { 3886 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 3887 } else { 3888 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 3889 } 3890 3891 if (events->sctp_association_event) { 3892 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 3893 } else { 3894 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 3895 } 3896 3897 if (events->sctp_address_event) { 3898 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 3899 } else { 3900 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 3901 } 3902 3903 if (events->sctp_send_failure_event) { 3904 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 3905 } else { 3906 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 3907 } 3908 3909 if (events->sctp_peer_error_event) { 3910 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR); 3911 } else { 3912 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR); 3913 } 3914 3915 if (events->sctp_shutdown_event) { 3916 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 3917 } else { 3918 sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 3919 } 3920 3921 if (events->sctp_partial_delivery_event) { 3922 sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 3923 } else { 3924 sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 3925 } 3926 3927 if (events->sctp_adaptation_layer_event) { 3928 sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 3929 } else { 3930 sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 3931 } 3932 3933 if (events->sctp_authentication_event) { 3934 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT); 3935 } else { 3936 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT); 3937 } 3938 3939 if (events->sctp_stream_reset_events) { 3940 sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 3941 } else { 3942 sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 3943 } 3944 SCTP_INP_WUNLOCK(inp); 3945 } 3946 break; 3947 3948 case SCTP_ADAPTATION_LAYER: 3949 { 3950 struct sctp_setadaptation *adap_bits; 3951 3952 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setadaptation)) { 3953 error = EINVAL; 3954 break; 3955 } 3956 SCTP_INP_WLOCK(inp); 3957 adap_bits = mtod(m, struct sctp_setadaptation *); 3958 inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind; 3959 SCTP_INP_WUNLOCK(inp); 3960 } 3961 break; 3962 case SCTP_SET_INITIAL_DBG_SEQ: 3963 { 3964 uint32_t *vvv; 3965 3966 if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) { 3967 error = EINVAL; 3968 break; 3969 } 3970 SCTP_INP_WLOCK(inp); 3971 vvv = mtod(m, uint32_t *); 3972 inp->sctp_ep.initial_sequence_debug = *vvv; 3973 SCTP_INP_WUNLOCK(inp); 3974 } 3975 break; 3976 case SCTP_DEFAULT_SEND_PARAM: 3977 { 3978 struct sctp_sndrcvinfo *s_info; 3979 3980 if (SCTP_BUF_LEN(m) != sizeof(struct sctp_sndrcvinfo)) { 3981 error = EINVAL; 3982 break; 3983 } 3984 s_info = mtod(m, struct sctp_sndrcvinfo *); 3985 3986 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3987 SCTP_INP_RLOCK(inp); 3988 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3989 if (stcb) 3990 SCTP_TCB_LOCK(stcb); 3991 SCTP_INP_RUNLOCK(inp); 3992 } else { 3993 if (s_info->sinfo_assoc_id) { 3994 stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id, 1); 3995 } else { 3996 stcb = NULL; 3997 } 3998 } 3999 if ((s_info->sinfo_assoc_id == 0) && 4000 (stcb == NULL)) { 4001 inp->def_send = *s_info; 4002 } else if (stcb == NULL) { 4003 error = ENOENT; 4004 break; 4005 } 4006 /* Validate things */ 4007 if (s_info->sinfo_stream > stcb->asoc.streamoutcnt) { 4008 SCTP_TCB_UNLOCK(stcb); 4009 error = EINVAL; 4010 break; 4011 } 4012 /* Copy it in */ 4013 stcb->asoc.def_send = *s_info; 4014 SCTP_TCB_UNLOCK(stcb); 4015 } 4016 break; 4017 case SCTP_PEER_ADDR_PARAMS: 4018 /* Applys to the specific association */ 4019 { 4020 struct sctp_paddrparams *paddrp; 4021 struct sctp_nets *net; 4022 4023 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrparams)) { 4024 error = EINVAL; 4025 break; 4026 } 4027 paddrp = mtod(m, struct sctp_paddrparams *); 4028 net = NULL; 4029 if (paddrp->spp_assoc_id) { 4030 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4031 SCTP_INP_RLOCK(inp); 4032 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4033 if (stcb) { 4034 SCTP_TCB_LOCK(stcb); 4035 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 4036 } 4037 SCTP_INP_RUNLOCK(inp); 4038 } else { 4039 stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id, 1); 4040 } 4041 if (stcb == NULL) { 4042 error = ENOENT; 4043 break; 4044 } 4045 } 4046 if ((stcb == NULL) && 4047 ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) || 4048 (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) { 4049 /* Lookup via address */ 4050 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4051 SCTP_INP_RLOCK(inp); 4052 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4053 if (stcb) { 4054 SCTP_TCB_LOCK(stcb); 4055 net = sctp_findnet(stcb, 4056 (struct sockaddr *)&paddrp->spp_address); 4057 } 4058 SCTP_INP_RUNLOCK(inp); 4059 } else { 4060 SCTP_INP_INCR_REF(inp); 4061 stcb = sctp_findassociation_ep_addr(&inp, 4062 (struct sockaddr *)&paddrp->spp_address, 4063 &net, NULL, NULL); 4064 if (stcb == NULL) { 4065 SCTP_INP_DECR_REF(inp); 4066 } 4067 } 4068 } 4069 if (stcb) { 4070 /************************TCB SPECIFIC SET ******************/ 4071 /* sack delay first */ 4072 if (paddrp->spp_flags & SPP_SACKDELAY_ENABLE) { 4073 /* 4074 * we do NOT support turning it off 4075 * (yet). only setting the delay. 4076 */ 4077 if (paddrp->spp_sackdelay >= SCTP_CLOCK_GRANULARITY) 4078 stcb->asoc.delayed_ack = paddrp->spp_sackdelay; 4079 else 4080 stcb->asoc.delayed_ack = SCTP_CLOCK_GRANULARITY; 4081 4082 } else if (paddrp->spp_flags & SPP_SACKDELAY_DISABLE) { 4083 stcb->asoc.delayed_ack = 0; 4084 } 4085 /* 4086 * do we change the timer for HB, we run 4087 * only one? 4088 */ 4089 if (paddrp->spp_hbinterval) 4090 stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval; 4091 else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) 4092 stcb->asoc.heart_beat_delay = 0; 4093 4094 /* network sets ? */ 4095 if (net) { 4096 /************************NET SPECIFIC SET ******************/ 4097 if (paddrp->spp_flags & SPP_HB_DEMAND) { 4098 /* on demand HB */ 4099 sctp_send_hb(stcb, 1, net); 4100 } 4101 if (paddrp->spp_flags & SPP_HB_DISABLE) { 4102 net->dest_state |= SCTP_ADDR_NOHB; 4103 } 4104 if (paddrp->spp_flags & SPP_HB_ENABLE) { 4105 net->dest_state &= ~SCTP_ADDR_NOHB; 4106 } 4107 if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { 4108 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 4109 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 4110 SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10); 4111 } 4112 if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) { 4113 net->mtu = paddrp->spp_pathmtu; 4114 if (net->mtu < stcb->asoc.smallest_mtu) 4115 sctp_pathmtu_adustment(inp, stcb, net, net->mtu); 4116 } 4117 } 4118 if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 4119 if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 4120 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 4121 } 4122 } 4123 if (paddrp->spp_pathmaxrxt) 4124 net->failure_threshold = paddrp->spp_pathmaxrxt; 4125 #ifdef AF_INET 4126 if (paddrp->spp_flags & SPP_IPV4_TOS) { 4127 if (net->ro._l_addr.sin.sin_family == AF_INET) { 4128 net->tos_flowlabel = paddrp->spp_ipv4_tos & 0x000000fc; 4129 } 4130 } 4131 #endif 4132 #ifdef AF_INET6 4133 if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 4134 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) { 4135 net->tos_flowlabel = paddrp->spp_ipv6_flowlabel; 4136 } 4137 } 4138 #endif 4139 } else { 4140 /************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/ 4141 if (paddrp->spp_pathmaxrxt) 4142 stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt; 4143 4144 if (paddrp->spp_flags & SPP_HB_ENABLE) { 4145 /* Turn back on the timer */ 4146 stcb->asoc.hb_is_disabled = 0; 4147 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 4148 } 4149 if (paddrp->spp_flags & SPP_HB_DISABLE) { 4150 int cnt_of_unconf = 0; 4151 struct sctp_nets *lnet; 4152 4153 stcb->asoc.hb_is_disabled = 1; 4154 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 4155 if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) { 4156 cnt_of_unconf++; 4157 } 4158 } 4159 /* 4160 * stop the timer ONLY if we 4161 * have no unconfirmed 4162 * addresses 4163 */ 4164 if (cnt_of_unconf == 0) { 4165 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11); 4166 } 4167 } 4168 if (paddrp->spp_flags & SPP_HB_ENABLE) { 4169 /* start up the timer. */ 4170 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 4171 } 4172 #ifdef AF_INET 4173 if (paddrp->spp_flags & SPP_IPV4_TOS) 4174 stcb->asoc.default_tos = paddrp->spp_ipv4_tos & 0x000000fc; 4175 #endif 4176 #ifdef AF_INET6 4177 if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) 4178 stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel; 4179 #endif 4180 4181 } 4182 SCTP_TCB_UNLOCK(stcb); 4183 } else { 4184 /************************NO TCB, SET TO default stuff ******************/ 4185 SCTP_INP_WLOCK(inp); 4186 /* 4187 * For the TOS/FLOWLABEL stuff you set it 4188 * with the options on the socket 4189 */ 4190 if (paddrp->spp_pathmaxrxt) { 4191 inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt; 4192 } 4193 if (paddrp->spp_flags & SPP_HB_ENABLE) { 4194 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval); 4195 sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 4196 } else if (paddrp->spp_flags & SPP_HB_DISABLE) { 4197 sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 4198 } 4199 if (paddrp->spp_flags & SPP_SACKDELAY_ENABLE) { 4200 if (paddrp->spp_sackdelay > SCTP_CLOCK_GRANULARITY) 4201 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(paddrp->spp_sackdelay); 4202 else 4203 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(SCTP_CLOCK_GRANULARITY); 4204 4205 } else if (paddrp->spp_flags & SPP_SACKDELAY_DISABLE) { 4206 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = 0; 4207 } 4208 SCTP_INP_WUNLOCK(inp); 4209 } 4210 } 4211 break; 4212 case SCTP_RTOINFO: 4213 { 4214 struct sctp_rtoinfo *srto; 4215 4216 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_rtoinfo)) { 4217 error = EINVAL; 4218 break; 4219 } 4220 srto = mtod(m, struct sctp_rtoinfo *); 4221 if (srto->srto_assoc_id == 0) { 4222 SCTP_INP_WLOCK(inp); 4223 /* 4224 * If we have a null asoc, its default for 4225 * the endpoint 4226 */ 4227 if (srto->srto_initial > 10) 4228 inp->sctp_ep.initial_rto = srto->srto_initial; 4229 if (srto->srto_max > 10) 4230 inp->sctp_ep.sctp_maxrto = srto->srto_max; 4231 if (srto->srto_min > 10) 4232 inp->sctp_ep.sctp_minrto = srto->srto_min; 4233 SCTP_INP_WUNLOCK(inp); 4234 break; 4235 } 4236 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4237 SCTP_INP_RLOCK(inp); 4238 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4239 if (stcb) 4240 SCTP_TCB_LOCK(stcb); 4241 SCTP_INP_RUNLOCK(inp); 4242 } else 4243 stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id, 1); 4244 if (stcb == NULL) { 4245 error = EINVAL; 4246 break; 4247 } 4248 /* Set in ms we hope :-) */ 4249 if (srto->srto_initial > 10) 4250 stcb->asoc.initial_rto = srto->srto_initial; 4251 if (srto->srto_max > 10) 4252 stcb->asoc.maxrto = srto->srto_max; 4253 if (srto->srto_min > 10) 4254 stcb->asoc.minrto = srto->srto_min; 4255 SCTP_TCB_UNLOCK(stcb); 4256 } 4257 break; 4258 case SCTP_ASSOCINFO: 4259 { 4260 struct sctp_assocparams *sasoc; 4261 4262 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assocparams)) { 4263 error = EINVAL; 4264 break; 4265 } 4266 sasoc = mtod(m, struct sctp_assocparams *); 4267 if (sasoc->sasoc_assoc_id) { 4268 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4269 SCTP_INP_RLOCK(inp); 4270 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4271 if (stcb) 4272 SCTP_TCB_LOCK(stcb); 4273 SCTP_INP_RUNLOCK(inp); 4274 } else 4275 stcb = sctp_findassociation_ep_asocid(inp, 4276 sasoc->sasoc_assoc_id, 1); 4277 if (stcb == NULL) { 4278 error = ENOENT; 4279 break; 4280 } 4281 } else { 4282 stcb = NULL; 4283 } 4284 if (stcb) { 4285 if (sasoc->sasoc_asocmaxrxt) 4286 stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt; 4287 sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets; 4288 sasoc->sasoc_peer_rwnd = 0; 4289 sasoc->sasoc_local_rwnd = 0; 4290 if (stcb->asoc.cookie_life) 4291 stcb->asoc.cookie_life = sasoc->sasoc_cookie_life; 4292 SCTP_TCB_UNLOCK(stcb); 4293 } else { 4294 SCTP_INP_WLOCK(inp); 4295 if (sasoc->sasoc_asocmaxrxt) 4296 inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt; 4297 sasoc->sasoc_number_peer_destinations = 0; 4298 sasoc->sasoc_peer_rwnd = 0; 4299 sasoc->sasoc_local_rwnd = 0; 4300 if (sasoc->sasoc_cookie_life) 4301 inp->sctp_ep.def_cookie_life = sasoc->sasoc_cookie_life; 4302 SCTP_INP_WUNLOCK(inp); 4303 } 4304 } 4305 break; 4306 case SCTP_INITMSG: 4307 { 4308 struct sctp_initmsg *sinit; 4309 4310 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_initmsg)) { 4311 error = EINVAL; 4312 break; 4313 } 4314 sinit = mtod(m, struct sctp_initmsg *); 4315 SCTP_INP_WLOCK(inp); 4316 if (sinit->sinit_num_ostreams) 4317 inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams; 4318 4319 if (sinit->sinit_max_instreams) 4320 inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams; 4321 4322 if (sinit->sinit_max_attempts) 4323 inp->sctp_ep.max_init_times = sinit->sinit_max_attempts; 4324 4325 if (sinit->sinit_max_init_timeo > 10) 4326 /* 4327 * We must be at least a 100ms (we set in 4328 * ticks) 4329 */ 4330 inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo; 4331 SCTP_INP_WUNLOCK(inp); 4332 } 4333 break; 4334 case SCTP_PRIMARY_ADDR: 4335 { 4336 struct sctp_setprim *spa; 4337 struct sctp_nets *net, *lnet; 4338 4339 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setprim)) { 4340 error = EINVAL; 4341 break; 4342 } 4343 spa = mtod(m, struct sctp_setprim *); 4344 4345 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4346 SCTP_INP_RLOCK(inp); 4347 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4348 if (stcb) { 4349 SCTP_TCB_LOCK(stcb); 4350 } else { 4351 error = EINVAL; 4352 break; 4353 } 4354 SCTP_INP_RUNLOCK(inp); 4355 } else 4356 stcb = sctp_findassociation_ep_asocid(inp, spa->ssp_assoc_id, 1); 4357 if (stcb == NULL) { 4358 /* One last shot */ 4359 SCTP_INP_INCR_REF(inp); 4360 stcb = sctp_findassociation_ep_addr(&inp, 4361 (struct sockaddr *)&spa->ssp_addr, 4362 &net, NULL, NULL); 4363 if (stcb == NULL) { 4364 SCTP_INP_DECR_REF(inp); 4365 error = EINVAL; 4366 break; 4367 } 4368 } else { 4369 /* 4370 * find the net, associd or connected lookup 4371 * type 4372 */ 4373 net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr); 4374 if (net == NULL) { 4375 SCTP_TCB_UNLOCK(stcb); 4376 error = EINVAL; 4377 break; 4378 } 4379 } 4380 if ((net != stcb->asoc.primary_destination) && 4381 (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) { 4382 /* Ok we need to set it */ 4383 lnet = stcb->asoc.primary_destination; 4384 if (sctp_set_primary_addr(stcb, 4385 (struct sockaddr *)NULL, 4386 net) == 0) { 4387 if (net->dest_state & SCTP_ADDR_SWITCH_PRIMARY) { 4388 net->dest_state |= SCTP_ADDR_DOUBLE_SWITCH; 4389 } 4390 net->dest_state |= SCTP_ADDR_SWITCH_PRIMARY; 4391 } 4392 } 4393 SCTP_TCB_UNLOCK(stcb); 4394 } 4395 break; 4396 4397 case SCTP_SET_PEER_PRIMARY_ADDR: 4398 { 4399 struct sctp_setpeerprim *sspp; 4400 4401 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setpeerprim)) { 4402 error = EINVAL; 4403 break; 4404 } 4405 sspp = mtod(m, struct sctp_setpeerprim *); 4406 4407 4408 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4409 SCTP_INP_RLOCK(inp); 4410 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4411 if (stcb) 4412 SCTP_TCB_UNLOCK(stcb); 4413 SCTP_INP_RUNLOCK(inp); 4414 } else 4415 stcb = sctp_findassociation_ep_asocid(inp, sspp->sspp_assoc_id, 1); 4416 if (stcb == NULL) { 4417 error = EINVAL; 4418 break; 4419 } 4420 if (sctp_set_primary_ip_address_sa(stcb, (struct sockaddr *)&sspp->sspp_addr) != 0) { 4421 error = EINVAL; 4422 } 4423 SCTP_TCB_UNLOCK(stcb); 4424 } 4425 break; 4426 case SCTP_BINDX_ADD_ADDR: 4427 { 4428 struct sctp_getaddresses *addrs; 4429 struct sockaddr *addr_touse; 4430 struct sockaddr_in sin; 4431 4432 /* see if we're bound all already! */ 4433 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 4434 error = EINVAL; 4435 break; 4436 } 4437 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) { 4438 error = EINVAL; 4439 break; 4440 } 4441 addrs = mtod(m, struct sctp_getaddresses *); 4442 addr_touse = addrs->addr; 4443 if (addrs->addr->sa_family == AF_INET6) { 4444 struct sockaddr_in6 *sin6; 4445 4446 sin6 = (struct sockaddr_in6 *)addr_touse; 4447 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 4448 in6_sin6_2_sin(&sin, sin6); 4449 addr_touse = (struct sockaddr *)&sin; 4450 } 4451 } 4452 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 4453 if (p == NULL) { 4454 /* Can't get proc for Net/Open BSD */ 4455 error = EINVAL; 4456 break; 4457 } 4458 error = sctp_inpcb_bind(so, addr_touse, p); 4459 break; 4460 } 4461 /* 4462 * No locks required here since bind and mgmt_ep_sa 4463 * all do their own locking. If we do something for 4464 * the FIX: below we may need to lock in that case. 4465 */ 4466 if (addrs->sget_assoc_id == 0) { 4467 /* add the address */ 4468 struct sctp_inpcb *lep; 4469 4470 ((struct sockaddr_in *)addr_touse)->sin_port = inp->sctp_lport; 4471 lep = sctp_pcb_findep(addr_touse, 1, 0); 4472 if (lep != NULL) { 4473 /* 4474 * We must decrement the refcount 4475 * since we have the ep already and 4476 * are binding. No remove going on 4477 * here. 4478 */ 4479 SCTP_INP_DECR_REF(inp); 4480 } 4481 if (lep == inp) { 4482 /* already bound to it.. ok */ 4483 break; 4484 } else if (lep == NULL) { 4485 ((struct sockaddr_in *)addr_touse)->sin_port = 0; 4486 error = sctp_addr_mgmt_ep_sa(inp, addr_touse, 4487 SCTP_ADD_IP_ADDRESS); 4488 } else { 4489 error = EADDRNOTAVAIL; 4490 } 4491 if (error) 4492 break; 4493 4494 } else { 4495 /* 4496 * FIX: decide whether we allow assoc based 4497 * bindx 4498 */ 4499 } 4500 } 4501 break; 4502 case SCTP_BINDX_REM_ADDR: 4503 { 4504 struct sctp_getaddresses *addrs; 4505 struct sockaddr *addr_touse; 4506 struct sockaddr_in sin; 4507 4508 /* see if we're bound all already! */ 4509 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 4510 error = EINVAL; 4511 break; 4512 } 4513 if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) { 4514 error = EINVAL; 4515 break; 4516 } 4517 addrs = mtod(m, struct sctp_getaddresses *); 4518 addr_touse = addrs->addr; 4519 if (addrs->addr->sa_family == AF_INET6) { 4520 struct sockaddr_in6 *sin6; 4521 4522 sin6 = (struct sockaddr_in6 *)addr_touse; 4523 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 4524 in6_sin6_2_sin(&sin, sin6); 4525 addr_touse = (struct sockaddr *)&sin; 4526 } 4527 } 4528 /* 4529 * No lock required mgmt_ep_sa does its own locking. 4530 * If the FIX: below is ever changed we may need to 4531 * lock before calling association level binding. 4532 */ 4533 if (addrs->sget_assoc_id == 0) { 4534 /* delete the address */ 4535 sctp_addr_mgmt_ep_sa(inp, addr_touse, 4536 SCTP_DEL_IP_ADDRESS); 4537 } else { 4538 /* 4539 * FIX: decide whether we allow assoc based 4540 * bindx 4541 */ 4542 } 4543 } 4544 break; 4545 default: 4546 error = ENOPROTOOPT; 4547 break; 4548 } /* end switch (opt) */ 4549 return (error); 4550 } 4551 4552 4553 4554 extern int sctp_chatty_mbuf; 4555 4556 int 4557 sctp_ctloutput(struct socket *so, struct sockopt *sopt) 4558 { 4559 struct mbuf *m = NULL; 4560 struct sctp_inpcb *inp; 4561 int s, error; 4562 4563 inp = (struct sctp_inpcb *)so->so_pcb; 4564 s = splnet(); 4565 if (inp == 0) { 4566 splx(s); 4567 /* I made the same as TCP since we are not setup? */ 4568 return (ECONNRESET); 4569 } 4570 if (sopt->sopt_level != IPPROTO_SCTP) { 4571 /* wrong proto level... send back up to IP */ 4572 #ifdef INET6 4573 if (INP_CHECK_SOCKAF(so, AF_INET6)) 4574 error = ip6_ctloutput(so, sopt); 4575 else 4576 #endif /* INET6 */ 4577 error = ip_ctloutput(so, sopt); 4578 splx(s); 4579 return (error); 4580 } 4581 if (sopt->sopt_valsize) { 4582 if (sopt->sopt_valsize < MLEN) { 4583 m = sctp_get_mbuf_for_msg(1, 0, M_WAIT, 1, MT_DATA); 4584 } else { 4585 m = sctp_get_mbuf_for_msg(sopt->sopt_valsize, 0, M_WAIT, 1, MT_DATA); 4586 } 4587 if (m == NULL) { 4588 sctp_m_freem(m); 4589 splx(s); 4590 return (ENOBUFS); 4591 } 4592 if (sopt->sopt_valsize > M_TRAILINGSPACE(m)) { 4593 /* Limit to actual size gotten */ 4594 sopt->sopt_valsize = M_TRAILINGSPACE(m); 4595 } 4596 error = sooptcopyin(sopt, mtod(m, caddr_t), sopt->sopt_valsize, 4597 sopt->sopt_valsize); 4598 if (error) { 4599 (void)sctp_m_free(m); 4600 goto out; 4601 } 4602 SCTP_BUF_LEN(m) = sopt->sopt_valsize; 4603 } 4604 if (sopt->sopt_dir == SOPT_SET) { 4605 error = sctp_optsset(so, sopt->sopt_name, &m, sopt->sopt_td); 4606 } else if (sopt->sopt_dir == SOPT_GET) { 4607 error = sctp_optsget(so, sopt->sopt_name, &m, sopt->sopt_td); 4608 } else { 4609 error = EINVAL; 4610 } 4611 if ((error == 0) && (m != NULL)) { 4612 error = sooptcopyout(sopt, mtod(m, caddr_t), SCTP_BUF_LEN(m)); 4613 sctp_m_freem(m); 4614 } else if (m != NULL) { 4615 sctp_m_freem(m); 4616 } 4617 out: 4618 splx(s); 4619 return (error); 4620 } 4621 4622 4623 static int 4624 sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) 4625 { 4626 int s = splnet(); 4627 4628 int error = 0; 4629 int create_lock_on = 0; 4630 struct sctp_inpcb *inp; 4631 struct sctp_tcb *stcb = NULL; 4632 4633 inp = (struct sctp_inpcb *)so->so_pcb; 4634 if (inp == 0) { 4635 splx(s); 4636 /* I made the same as TCP since we are not setup? */ 4637 return (ECONNRESET); 4638 } 4639 SCTP_ASOC_CREATE_LOCK(inp); 4640 create_lock_on = 1; 4641 4642 SCTP_INP_INCR_REF(inp); 4643 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 4644 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 4645 /* Should I really unlock ? */ 4646 error = EFAULT; 4647 goto out_now; 4648 } 4649 #ifdef INET6 4650 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 4651 (addr->sa_family == AF_INET6)) { 4652 error = EINVAL; 4653 goto out_now; 4654 } 4655 #endif /* INET6 */ 4656 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 4657 SCTP_PCB_FLAGS_UNBOUND) { 4658 /* Bind a ephemeral port */ 4659 error = sctp_inpcb_bind(so, NULL, p); 4660 if (error) { 4661 goto out_now; 4662 } 4663 } 4664 /* Now do we connect? */ 4665 if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) { 4666 error = EINVAL; 4667 goto out_now; 4668 } 4669 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 4670 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 4671 /* We are already connected AND the TCP model */ 4672 error = EADDRINUSE; 4673 goto out_now; 4674 } 4675 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4676 SCTP_INP_RLOCK(inp); 4677 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4678 if (stcb) 4679 SCTP_TCB_UNLOCK(stcb); 4680 SCTP_INP_RUNLOCK(inp); 4681 } else { 4682 /* 4683 * Raise the count a second time, since on sucess 4684 * f-a-ep_addr will decrement it. 4685 */ 4686 SCTP_INP_INCR_REF(inp); 4687 stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 4688 if (stcb == NULL) { 4689 SCTP_INP_DECR_REF(inp); 4690 } 4691 } 4692 if (stcb != NULL) { 4693 /* Already have or am bring up an association */ 4694 error = EALREADY; 4695 goto out_now; 4696 } 4697 /* We are GOOD to go */ 4698 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0); 4699 if (stcb == NULL) { 4700 /* Gak! no memory */ 4701 splx(s); 4702 return (error); 4703 } 4704 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 4705 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 4706 /* Set the connected flag so we can queue data */ 4707 soisconnecting(so); 4708 } 4709 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT; 4710 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 4711 4712 /* initialize authentication parameters for the assoc */ 4713 sctp_initialize_auth_params(inp, stcb); 4714 4715 sctp_send_initiate(inp, stcb); 4716 out_now: 4717 if (create_lock_on) 4718 SCTP_ASOC_CREATE_UNLOCK(inp); 4719 4720 if (stcb) 4721 SCTP_TCB_UNLOCK(stcb); 4722 SCTP_INP_DECR_REF(inp); 4723 splx(s); 4724 return error; 4725 } 4726 4727 int 4728 sctp_listen(struct socket *so, int backlog, struct thread *p) 4729 { 4730 /* 4731 * Note this module depends on the protocol processing being called 4732 * AFTER any socket level flags and backlog are applied to the 4733 * socket. The traditional way that the socket flags are applied is 4734 * AFTER protocol processing. We have made a change to the 4735 * sys/kern/uipc_socket.c module to reverse this but this MUST be in 4736 * place if the socket API for SCTP is to work properly. 4737 */ 4738 int s = splnet(); 4739 4740 int error = 0; 4741 struct sctp_inpcb *inp; 4742 4743 inp = (struct sctp_inpcb *)so->so_pcb; 4744 if (inp == 0) { 4745 splx(s); 4746 /* I made the same as TCP since we are not setup? */ 4747 return (ECONNRESET); 4748 } 4749 SCTP_INP_RLOCK(inp); 4750 #ifdef SCTP_LOCK_LOGGING 4751 sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK); 4752 #endif 4753 SOCK_LOCK(so); 4754 error = solisten_proto_check(so); 4755 if (error) { 4756 SOCK_UNLOCK(so); 4757 return (error); 4758 } 4759 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 4760 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 4761 /* We are already connected AND the TCP model */ 4762 splx(s); 4763 SCTP_INP_RUNLOCK(inp); 4764 SOCK_UNLOCK(so); 4765 return (EADDRINUSE); 4766 } 4767 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 4768 /* We must do a bind. */ 4769 SCTP_INP_RUNLOCK(inp); 4770 if ((error = sctp_inpcb_bind(so, NULL, p))) { 4771 /* bind error, probably perm */ 4772 SOCK_UNLOCK(so); 4773 splx(s); 4774 return (error); 4775 } 4776 } else { 4777 SCTP_INP_RUNLOCK(inp); 4778 } 4779 /* It appears for 7.0 and on, we must always call this. */ 4780 solisten_proto(so, backlog); 4781 4782 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 4783 /* remove the ACCEPTCONN flag for one-to-many sockets */ 4784 so->so_options &= ~SO_ACCEPTCONN; 4785 } 4786 if (backlog == 0) { 4787 /* turning off listen */ 4788 so->so_options &= ~SO_ACCEPTCONN; 4789 } 4790 SOCK_UNLOCK(so); 4791 splx(s); 4792 return (error); 4793 } 4794 4795 static int sctp_defered_wakeup_cnt = 0; 4796 4797 int 4798 sctp_accept(struct socket *so, struct sockaddr **addr) 4799 { 4800 int s = splnet(); 4801 4802 struct sctp_tcb *stcb; 4803 struct sctp_inpcb *inp; 4804 union sctp_sockstore store; 4805 4806 int error; 4807 4808 4809 inp = (struct sctp_inpcb *)so->so_pcb; 4810 4811 if (inp == 0) { 4812 splx(s); 4813 return (ECONNRESET); 4814 } 4815 SCTP_INP_RLOCK(inp); 4816 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 4817 return (ENOTSUP); 4818 } 4819 if (so->so_state & SS_ISDISCONNECTED) { 4820 splx(s); 4821 SCTP_INP_RUNLOCK(inp); 4822 return (ECONNABORTED); 4823 } 4824 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4825 if (stcb == NULL) { 4826 splx(s); 4827 SCTP_INP_RUNLOCK(inp); 4828 return (ECONNRESET); 4829 } 4830 SCTP_TCB_LOCK(stcb); 4831 SCTP_INP_RUNLOCK(inp); 4832 store = stcb->asoc.primary_destination->ro._l_addr; 4833 SCTP_TCB_UNLOCK(stcb); 4834 if (store.sa.sa_family == AF_INET) { 4835 struct sockaddr_in *sin; 4836 4837 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 4838 sin->sin_family = AF_INET; 4839 sin->sin_len = sizeof(*sin); 4840 sin->sin_port = ((struct sockaddr_in *)&store)->sin_port; 4841 sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr; 4842 *addr = (struct sockaddr *)sin; 4843 } else { 4844 struct sockaddr_in6 *sin6; 4845 4846 SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); 4847 sin6->sin6_family = AF_INET6; 4848 sin6->sin6_len = sizeof(*sin6); 4849 sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port; 4850 4851 sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr; 4852 if ((error = sa6_recoverscope(sin6)) != 0) { 4853 SCTP_FREE_SONAME(sin6); 4854 return (error); 4855 } 4856 *addr = (struct sockaddr *)sin6; 4857 } 4858 /* Wake any delayed sleep action */ 4859 if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { 4860 inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE; 4861 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) { 4862 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; 4863 SOCKBUF_LOCK(&inp->sctp_socket->so_snd); 4864 if (sowriteable(inp->sctp_socket)) { 4865 sowwakeup_locked(inp->sctp_socket); 4866 } else { 4867 SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd); 4868 } 4869 } 4870 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) { 4871 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; 4872 SOCKBUF_LOCK(&inp->sctp_socket->so_rcv); 4873 if (soreadable(inp->sctp_socket)) { 4874 sctp_defered_wakeup_cnt++; 4875 sorwakeup_locked(inp->sctp_socket); 4876 } else { 4877 SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv); 4878 } 4879 } 4880 } 4881 splx(s); 4882 return (0); 4883 } 4884 4885 int 4886 sctp_ingetaddr(struct socket *so, struct sockaddr **addr) 4887 { 4888 struct sockaddr_in *sin; 4889 4890 int s; 4891 struct sctp_inpcb *inp; 4892 4893 /* 4894 * Do the malloc first in case it blocks. 4895 */ 4896 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 4897 sin->sin_family = AF_INET; 4898 sin->sin_len = sizeof(*sin); 4899 s = splnet(); 4900 inp = (struct sctp_inpcb *)so->so_pcb; 4901 if (!inp) { 4902 splx(s); 4903 SCTP_FREE_SONAME(sin); 4904 return ECONNRESET; 4905 } 4906 SCTP_INP_RLOCK(inp); 4907 sin->sin_port = inp->sctp_lport; 4908 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 4909 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 4910 struct sctp_tcb *stcb; 4911 struct sockaddr_in *sin_a; 4912 struct sctp_nets *net; 4913 int fnd; 4914 4915 stcb = LIST_FIRST(&inp->sctp_asoc_list); 4916 if (stcb == NULL) { 4917 goto notConn; 4918 } 4919 fnd = 0; 4920 sin_a = NULL; 4921 SCTP_TCB_LOCK(stcb); 4922 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 4923 sin_a = (struct sockaddr_in *)&net->ro._l_addr; 4924 if (sin_a == NULL) 4925 /* this will make coverity happy */ 4926 continue; 4927 4928 if (sin_a->sin_family == AF_INET) { 4929 fnd = 1; 4930 break; 4931 } 4932 } 4933 if ((!fnd) || (sin_a == NULL)) { 4934 /* punt */ 4935 SCTP_TCB_UNLOCK(stcb); 4936 goto notConn; 4937 } 4938 sin->sin_addr = sctp_ipv4_source_address_selection(inp, 4939 stcb, (struct route *)&net->ro, net, 0); 4940 SCTP_TCB_UNLOCK(stcb); 4941 } else { 4942 /* For the bound all case you get back 0 */ 4943 notConn: 4944 sin->sin_addr.s_addr = 0; 4945 } 4946 4947 } else { 4948 /* Take the first IPv4 address in the list */ 4949 struct sctp_laddr *laddr; 4950 int fnd = 0; 4951 4952 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 4953 if (laddr->ifa->ifa_addr->sa_family == AF_INET) { 4954 struct sockaddr_in *sin_a; 4955 4956 sin_a = (struct sockaddr_in *)laddr->ifa->ifa_addr; 4957 sin->sin_addr = sin_a->sin_addr; 4958 fnd = 1; 4959 break; 4960 } 4961 } 4962 if (!fnd) { 4963 splx(s); 4964 SCTP_FREE_SONAME(sin); 4965 SCTP_INP_RUNLOCK(inp); 4966 return ENOENT; 4967 } 4968 } 4969 SCTP_INP_RUNLOCK(inp); 4970 splx(s); 4971 (*addr) = (struct sockaddr *)sin; 4972 return (0); 4973 } 4974 4975 int 4976 sctp_peeraddr(struct socket *so, struct sockaddr **addr) 4977 { 4978 struct sockaddr_in *sin = (struct sockaddr_in *)*addr; 4979 4980 int s, fnd; 4981 struct sockaddr_in *sin_a; 4982 struct sctp_inpcb *inp; 4983 struct sctp_tcb *stcb; 4984 struct sctp_nets *net; 4985 4986 4987 /* Do the malloc first in case it blocks. */ 4988 inp = (struct sctp_inpcb *)so->so_pcb; 4989 if ((inp == NULL) || 4990 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) { 4991 /* UDP type and listeners will drop out here */ 4992 return (ENOTCONN); 4993 } 4994 s = splnet(); 4995 4996 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 4997 sin->sin_family = AF_INET; 4998 sin->sin_len = sizeof(*sin); 4999 5000 /* We must recapture incase we blocked */ 5001 inp = (struct sctp_inpcb *)so->so_pcb; 5002 if (!inp) { 5003 splx(s); 5004 SCTP_FREE_SONAME(sin); 5005 return ECONNRESET; 5006 } 5007 SCTP_INP_RLOCK(inp); 5008 stcb = LIST_FIRST(&inp->sctp_asoc_list); 5009 if (stcb) 5010 SCTP_TCB_LOCK(stcb); 5011 SCTP_INP_RUNLOCK(inp); 5012 if (stcb == NULL) { 5013 splx(s); 5014 SCTP_FREE_SONAME(sin); 5015 return ECONNRESET; 5016 } 5017 fnd = 0; 5018 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 5019 sin_a = (struct sockaddr_in *)&net->ro._l_addr; 5020 if (sin_a->sin_family == AF_INET) { 5021 fnd = 1; 5022 sin->sin_port = stcb->rport; 5023 sin->sin_addr = sin_a->sin_addr; 5024 break; 5025 } 5026 } 5027 SCTP_TCB_UNLOCK(stcb); 5028 if (!fnd) { 5029 /* No IPv4 address */ 5030 splx(s); 5031 SCTP_FREE_SONAME(sin); 5032 return ENOENT; 5033 } 5034 splx(s); 5035 (*addr) = (struct sockaddr *)sin; 5036 return (0); 5037 } 5038 5039 struct pr_usrreqs sctp_usrreqs = { 5040 .pru_abort = sctp_abort, 5041 .pru_accept = sctp_accept, 5042 .pru_attach = sctp_attach, 5043 .pru_bind = sctp_bind, 5044 .pru_connect = sctp_connect, 5045 .pru_control = in_control, 5046 .pru_close = sctp_close, 5047 .pru_detach = sctp_close, 5048 .pru_sopoll = sopoll_generic, 5049 .pru_disconnect = sctp_disconnect, 5050 .pru_listen = sctp_listen, 5051 .pru_peeraddr = sctp_peeraddr, 5052 .pru_send = sctp_sendm, 5053 .pru_shutdown = sctp_shutdown, 5054 .pru_sockaddr = sctp_ingetaddr, 5055 .pru_sosend = sctp_sosend, 5056 .pru_soreceive = sctp_soreceive 5057 }; 5058