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