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