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