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