1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1676 jpk * Common Development and Distribution License (the "License"). 6 1676 jpk * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 1735 kcpoon 22 0 stevel /* 23 8778 Erik * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel #include <sys/types.h> 28 0 stevel #include <sys/systm.h> 29 0 stevel #include <sys/stream.h> 30 0 stevel #include <sys/cmn_err.h> 31 0 stevel #include <sys/kmem.h> 32 0 stevel #define _SUN_TPI_VERSION 2 33 0 stevel #include <sys/tihdr.h> 34 0 stevel #include <sys/stropts.h> 35 0 stevel #include <sys/strsubr.h> 36 0 stevel #include <sys/socket.h> 37 1676 jpk #include <sys/tsol/tndb.h> 38 0 stevel 39 0 stevel #include <netinet/in.h> 40 0 stevel #include <netinet/ip6.h> 41 0 stevel 42 0 stevel #include <inet/common.h> 43 0 stevel #include <inet/ip.h> 44 0 stevel #include <inet/ip6.h> 45 0 stevel #include <inet/ipclassifier.h> 46 0 stevel #include <inet/ipsec_impl.h> 47 0 stevel 48 0 stevel #include "sctp_impl.h" 49 0 stevel #include "sctp_addr.h" 50 0 stevel 51 0 stevel /* 52 0 stevel * Common accept code. Called by sctp_conn_request. 53 0 stevel * cr_pkt is the INIT / INIT ACK packet. 54 0 stevel */ 55 0 stevel static int 56 0 stevel sctp_accept_comm(sctp_t *listener, sctp_t *acceptor, mblk_t *cr_pkt, 57 0 stevel uint_t ip_hdr_len, sctp_init_chunk_t *iack) 58 0 stevel { 59 0 stevel 60 0 stevel sctp_hdr_t *sctph; 61 0 stevel sctp_chunk_hdr_t *ich; 62 0 stevel sctp_init_chunk_t *init; 63 0 stevel int err; 64 0 stevel uint_t sctp_options; 65 2776 kp158701 conn_t *aconnp; 66 1676 jpk conn_t *lconnp; 67 3448 dh155122 sctp_stack_t *sctps = listener->sctp_sctps; 68 0 stevel 69 0 stevel sctph = (sctp_hdr_t *)(cr_pkt->b_rptr + ip_hdr_len); 70 0 stevel ASSERT(OK_32PTR(sctph)); 71 0 stevel 72 11042 Erik aconnp = acceptor->sctp_connp; 73 11042 Erik lconnp = listener->sctp_connp; 74 11042 Erik aconnp->conn_lport = lconnp->conn_lport; 75 11042 Erik aconnp->conn_fport = sctph->sh_sport; 76 0 stevel 77 0 stevel ich = (sctp_chunk_hdr_t *)(iack + 1); 78 0 stevel init = (sctp_init_chunk_t *)(ich + 1); 79 9710 Ken 80 0 stevel /* acceptor isn't in any fanouts yet, so don't need to hold locks */ 81 0 stevel ASSERT(acceptor->sctp_faddrs == NULL); 82 0 stevel err = sctp_get_addrparams(acceptor, listener, cr_pkt, ich, 83 0 stevel &sctp_options); 84 0 stevel if (err != 0) 85 0 stevel return (err); 86 1676 jpk 87 1735 kcpoon if ((err = sctp_set_hdraddrs(acceptor)) != 0) 88 1676 jpk return (err); 89 1676 jpk 90 11042 Erik if ((err = sctp_build_hdrs(acceptor, KM_NOSLEEP)) != 0) 91 11042 Erik return (err); 92 11042 Erik 93 0 stevel if ((sctp_options & SCTP_PRSCTP_OPTION) && 94 3448 dh155122 listener->sctp_prsctp_aware && sctps->sctps_prsctp_enabled) { 95 0 stevel acceptor->sctp_prsctp_aware = B_TRUE; 96 0 stevel } else { 97 0 stevel acceptor->sctp_prsctp_aware = B_FALSE; 98 0 stevel } 99 0 stevel 100 0 stevel /* Get initial TSNs */ 101 0 stevel acceptor->sctp_ltsn = ntohl(iack->sic_inittsn); 102 0 stevel acceptor->sctp_recovery_tsn = acceptor->sctp_lastack_rxd = 103 0 stevel acceptor->sctp_ltsn - 1; 104 0 stevel acceptor->sctp_adv_pap = acceptor->sctp_lastack_rxd; 105 0 stevel /* Serial numbers are initialized to the same value as the TSNs */ 106 0 stevel acceptor->sctp_lcsn = acceptor->sctp_ltsn; 107 0 stevel 108 0 stevel if (!sctp_initialize_params(acceptor, init, iack)) 109 0 stevel return (ENOMEM); 110 0 stevel 111 0 stevel /* 112 0 stevel * Copy sctp_secret from the listener in case we need to validate 113 0 stevel * a possibly delayed cookie. 114 0 stevel */ 115 0 stevel bcopy(listener->sctp_secret, acceptor->sctp_secret, SCTP_SECRET_LEN); 116 0 stevel bcopy(listener->sctp_old_secret, acceptor->sctp_old_secret, 117 0 stevel SCTP_SECRET_LEN); 118 11066 rafael acceptor->sctp_last_secret_update = ddi_get_lbolt64(); 119 0 stevel 120 0 stevel /* 121 0 stevel * After acceptor is inserted in the hash list, it can be found. 122 0 stevel * So we need to lock it here. 123 0 stevel */ 124 0 stevel RUN_SCTP(acceptor); 125 0 stevel 126 3448 dh155122 sctp_conn_hash_insert(&sctps->sctps_conn_fanout[ 127 11042 Erik SCTP_CONN_HASH(sctps, aconnp->conn_ports)], acceptor, 0); 128 3448 dh155122 sctp_bind_hash_insert(&sctps->sctps_bind_fanout[ 129 11042 Erik SCTP_BIND_HASH(ntohs(aconnp->conn_lport))], acceptor, 0); 130 0 stevel 131 0 stevel /* 132 0 stevel * No need to check for multicast destination since ip will only pass 133 0 stevel * up multicasts to those that have expressed interest 134 0 stevel * TODO: what about rejecting broadcasts? 135 0 stevel * Also check that source is not a multicast or broadcast address. 136 0 stevel */ 137 0 stevel /* XXXSCTP */ 138 0 stevel acceptor->sctp_state = SCTPS_ESTABLISHED; 139 11066 rafael acceptor->sctp_assoc_start_time = (uint32_t)ddi_get_lbolt(); 140 0 stevel /* 141 0 stevel * listener->sctp_rwnd should be the default window size or a 142 0 stevel * window size changed via SO_RCVBUF option. 143 0 stevel */ 144 852 vi117747 acceptor->sctp_rwnd = listener->sctp_rwnd; 145 852 vi117747 acceptor->sctp_irwnd = acceptor->sctp_rwnd; 146 3845 vi117747 acceptor->sctp_pd_point = acceptor->sctp_rwnd; 147 8348 Eric acceptor->sctp_upcalls = listener->sctp_upcalls; 148 0 stevel 149 0 stevel return (0); 150 0 stevel } 151 0 stevel 152 0 stevel /* Process the COOKIE packet, mp, directed at the listener 'sctp' */ 153 0 stevel sctp_t * 154 0 stevel sctp_conn_request(sctp_t *sctp, mblk_t *mp, uint_t ifindex, uint_t ip_hdr_len, 155 11042 Erik sctp_init_chunk_t *iack, ip_recv_attr_t *ira) 156 0 stevel { 157 0 stevel sctp_t *eager; 158 0 stevel ip6_t *ip6h; 159 0 stevel int err; 160 0 stevel conn_t *connp, *econnp; 161 3448 dh155122 sctp_stack_t *sctps; 162 8348 Eric struct sock_proto_props sopp; 163 8778 Erik cred_t *cr; 164 8778 Erik pid_t cpid; 165 11042 Erik in6_addr_t faddr, laddr; 166 11042 Erik ip_xmit_attr_t *ixa; 167 0 stevel 168 0 stevel /* 169 0 stevel * No need to check for duplicate as this is the listener 170 0 stevel * and we are holding the lock. This means that no new 171 0 stevel * connection can be created out of it. And since the 172 0 stevel * fanout already done cannot find a match, it means that 173 0 stevel * there is no duplicate. 174 0 stevel */ 175 0 stevel ASSERT(OK_32PTR(mp->b_rptr)); 176 0 stevel 177 0 stevel if ((eager = sctp_create_eager(sctp)) == NULL) { 178 0 stevel return (NULL); 179 0 stevel } 180 0 stevel 181 0 stevel connp = sctp->sctp_connp; 182 3448 dh155122 sctps = sctp->sctp_sctps; 183 0 stevel econnp = eager->sctp_connp; 184 0 stevel 185 0 stevel if (connp->conn_policy != NULL) { 186 11042 Erik /* Inherit the policy from the listener; use actions from ira */ 187 11042 Erik if (!ip_ipsec_policy_inherit(econnp, connp, ira)) { 188 0 stevel sctp_close_eager(eager); 189 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 190 0 stevel return (NULL); 191 0 stevel } 192 0 stevel } 193 0 stevel 194 11042 Erik ip6h = (ip6_t *)mp->b_rptr; 195 11042 Erik if (ira->ira_flags & IXAF_IS_IPV4) { 196 11042 Erik ipha_t *ipha; 197 11042 Erik 198 11042 Erik ipha = (ipha_t *)ip6h; 199 11042 Erik IN6_IPADDR_TO_V4MAPPED(ipha->ipha_dst, &laddr); 200 11042 Erik IN6_IPADDR_TO_V4MAPPED(ipha->ipha_src, &faddr); 201 11042 Erik } else { 202 11042 Erik laddr = ip6h->ip6_dst; 203 11042 Erik faddr = ip6h->ip6_src; 204 11042 Erik } 205 11042 Erik 206 11042 Erik if (ira->ira_flags & IRAF_IPSEC_SECURE) { 207 0 stevel /* 208 0 stevel * XXX need to fix the cached policy issue here. 209 11042 Erik * We temporarily set the conn_laddr/conn_faddr here so 210 0 stevel * that IPsec can use it for the latched policy 211 0 stevel * selector. This is obvioursly wrong as SCTP can 212 0 stevel * use different addresses... 213 0 stevel */ 214 11042 Erik econnp->conn_laddr_v6 = laddr; 215 11042 Erik econnp->conn_faddr_v6 = faddr; 216 11042 Erik econnp->conn_saddr_v6 = laddr; 217 0 stevel } 218 11042 Erik if (ipsec_conn_cache_policy(econnp, 219 11042 Erik (ira->ira_flags & IRAF_IS_IPV4) != 0) != 0) { 220 0 stevel sctp_close_eager(eager); 221 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 222 0 stevel return (NULL); 223 0 stevel } 224 0 stevel 225 8778 Erik /* Save for getpeerucred */ 226 11042 Erik cr = ira->ira_cred; 227 11042 Erik cpid = ira->ira_cpid; 228 11042 Erik 229 11042 Erik if (is_system_labeled()) { 230 11042 Erik ip_xmit_attr_t *ixa = econnp->conn_ixa; 231 11042 Erik 232 11042 Erik ASSERT(ira->ira_tsl != NULL); 233 11042 Erik 234 11042 Erik /* Discard any old label */ 235 11042 Erik if (ixa->ixa_free_flags & IXA_FREE_TSL) { 236 11042 Erik ASSERT(ixa->ixa_tsl != NULL); 237 11042 Erik label_rele(ixa->ixa_tsl); 238 11042 Erik ixa->ixa_free_flags &= ~IXA_FREE_TSL; 239 11042 Erik ixa->ixa_tsl = NULL; 240 11042 Erik } 241 11042 Erik 242 11042 Erik if ((connp->conn_mlp_type != mlptSingle || 243 11042 Erik connp->conn_mac_mode != CONN_MAC_DEFAULT) && 244 11042 Erik ira->ira_tsl != NULL) { 245 11042 Erik /* 246 11042 Erik * If this is an MLP connection or a MAC-Exempt 247 11042 Erik * connection with an unlabeled node, packets are to be 248 11042 Erik * exchanged using the security label of the received 249 11042 Erik * Cookie packet instead of the server application's 250 11042 Erik * label. 251 11042 Erik * tsol_check_dest called from ip_set_destination 252 11042 Erik * might later update TSF_UNLABELED by replacing 253 11042 Erik * ixa_tsl with a new label. 254 11042 Erik */ 255 11042 Erik label_hold(ira->ira_tsl); 256 11042 Erik ip_xmit_attr_replace_tsl(ixa, ira->ira_tsl); 257 11042 Erik } else { 258 11042 Erik ixa->ixa_tsl = crgetlabel(econnp->conn_cred); 259 11042 Erik } 260 11042 Erik } 261 8778 Erik 262 0 stevel err = sctp_accept_comm(sctp, eager, mp, ip_hdr_len, iack); 263 11042 Erik if (err != 0) { 264 0 stevel sctp_close_eager(eager); 265 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 266 0 stevel return (NULL); 267 11042 Erik } 268 11042 Erik 269 11042 Erik ASSERT(eager->sctp_current->ixa != NULL); 270 11042 Erik 271 11042 Erik ixa = eager->sctp_current->ixa; 272 11042 Erik if (!(ira->ira_flags & IXAF_IS_IPV4)) { 273 11042 Erik ASSERT(!(ixa->ixa_flags & IXAF_IS_IPV4)); 274 11042 Erik 275 11042 Erik if (IN6_IS_ADDR_LINKLOCAL(&ip6h->ip6_src) || 276 11042 Erik IN6_IS_ADDR_LINKLOCAL(&ip6h->ip6_dst)) { 277 11042 Erik eager->sctp_linklocal = 1; 278 11042 Erik 279 11042 Erik ixa->ixa_flags |= IXAF_SCOPEID_SET; 280 11042 Erik ixa->ixa_scopeid = ifindex; 281 11042 Erik econnp->conn_incoming_ifindex = ifindex; 282 11042 Erik } 283 0 stevel } 284 0 stevel 285 852 vi117747 /* 286 852 vi117747 * On a clustered note send this notification to the clustering 287 852 vi117747 * subsystem. 288 852 vi117747 */ 289 852 vi117747 if (cl_sctp_connect != NULL) { 290 852 vi117747 uchar_t *slist; 291 852 vi117747 uchar_t *flist; 292 852 vi117747 size_t fsize; 293 852 vi117747 size_t ssize; 294 852 vi117747 295 852 vi117747 fsize = sizeof (in6_addr_t) * eager->sctp_nfaddrs; 296 852 vi117747 ssize = sizeof (in6_addr_t) * eager->sctp_nsaddrs; 297 852 vi117747 slist = kmem_alloc(ssize, KM_NOSLEEP); 298 852 vi117747 flist = kmem_alloc(fsize, KM_NOSLEEP); 299 852 vi117747 if (slist == NULL || flist == NULL) { 300 852 vi117747 if (slist != NULL) 301 852 vi117747 kmem_free(slist, ssize); 302 852 vi117747 if (flist != NULL) 303 852 vi117747 kmem_free(flist, fsize); 304 852 vi117747 sctp_close_eager(eager); 305 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 306 3448 dh155122 SCTP_KSTAT(sctps, sctp_cl_connect); 307 852 vi117747 return (NULL); 308 852 vi117747 } 309 852 vi117747 /* The clustering module frees these list */ 310 852 vi117747 sctp_get_saddr_list(eager, slist, ssize); 311 852 vi117747 sctp_get_faddr_list(eager, flist, fsize); 312 11042 Erik (*cl_sctp_connect)(econnp->conn_family, slist, 313 11042 Erik eager->sctp_nsaddrs, econnp->conn_lport, flist, 314 11042 Erik eager->sctp_nfaddrs, econnp->conn_fport, B_FALSE, 315 852 vi117747 (cl_sctp_handle_t)eager); 316 852 vi117747 } 317 852 vi117747 318 0 stevel /* Connection established, so send up the conn_ind */ 319 0 stevel if ((eager->sctp_ulpd = sctp->sctp_ulp_newconn(sctp->sctp_ulpd, 320 8778 Erik (sock_lower_handle_t)eager, NULL, cr, cpid, 321 8348 Eric &eager->sctp_upcalls)) == NULL) { 322 0 stevel sctp_close_eager(eager); 323 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 324 0 stevel return (NULL); 325 0 stevel } 326 0 stevel ASSERT(SCTP_IS_DETACHED(eager)); 327 0 stevel eager->sctp_detached = B_FALSE; 328 8348 Eric bzero(&sopp, sizeof (sopp)); 329 8348 Eric sopp.sopp_flags = SOCKOPT_MAXBLK|SOCKOPT_WROFF; 330 8348 Eric sopp.sopp_maxblk = strmsgsz; 331 11042 Erik if (econnp->conn_family == AF_INET) { 332 8348 Eric sopp.sopp_wroff = sctps->sctps_wroff_xtra + 333 8348 Eric sizeof (sctp_data_hdr_t) + sctp->sctp_hdr_len; 334 0 stevel } else { 335 8348 Eric sopp.sopp_wroff = sctps->sctps_wroff_xtra + 336 8348 Eric sizeof (sctp_data_hdr_t) + sctp->sctp_hdr6_len; 337 0 stevel } 338 8348 Eric eager->sctp_ulp_prop(eager->sctp_ulpd, &sopp); 339 0 stevel return (eager); 340 0 stevel } 341 0 stevel 342 0 stevel /* 343 0 stevel * Connect to a peer - this function inserts the sctp in the 344 0 stevel * bind and conn fanouts, sends the INIT, and replies to the client 345 0 stevel * with an OK ack. 346 0 stevel */ 347 0 stevel int 348 11042 Erik sctp_connect(sctp_t *sctp, const struct sockaddr *dst, uint32_t addrlen, 349 11042 Erik cred_t *cr, pid_t pid) 350 0 stevel { 351 0 stevel sin_t *sin; 352 0 stevel sin6_t *sin6; 353 0 stevel in6_addr_t dstaddr; 354 0 stevel in_port_t dstport; 355 0 stevel mblk_t *initmp; 356 0 stevel sctp_tf_t *tbf; 357 0 stevel sctp_t *lsctp; 358 0 stevel char buf[INET6_ADDRSTRLEN]; 359 0 stevel int sleep = sctp->sctp_cansleep ? KM_SLEEP : KM_NOSLEEP; 360 1676 jpk int err; 361 0 stevel sctp_faddr_t *cur_fp; 362 3448 dh155122 sctp_stack_t *sctps = sctp->sctp_sctps; 363 11042 Erik conn_t *connp = sctp->sctp_connp; 364 11042 Erik uint_t scope_id = 0; 365 11042 Erik ip_xmit_attr_t *ixa; 366 0 stevel 367 0 stevel /* 368 0 stevel * Determine packet type based on type of address passed in 369 0 stevel * the request should contain an IPv4 or IPv6 address. 370 0 stevel * Make sure that address family matches the type of 371 11042 Erik * family of the address passed down. 372 0 stevel */ 373 0 stevel if (addrlen < sizeof (sin_t)) { 374 0 stevel return (EINVAL); 375 0 stevel } 376 0 stevel switch (dst->sa_family) { 377 0 stevel case AF_INET: 378 0 stevel sin = (sin_t *)dst; 379 0 stevel 380 0 stevel /* Check for attempt to connect to non-unicast */ 381 5215 kcpoon if (CLASSD(sin->sin_addr.s_addr) || 382 0 stevel (sin->sin_addr.s_addr == INADDR_BROADCAST)) { 383 0 stevel ip0dbg(("sctp_connect: non-unicast\n")); 384 0 stevel return (EINVAL); 385 0 stevel } 386 11042 Erik if (connp->conn_ipv6_v6only) 387 0 stevel return (EAFNOSUPPORT); 388 0 stevel 389 0 stevel /* convert to v6 mapped */ 390 0 stevel /* Check for attempt to connect to INADDR_ANY */ 391 0 stevel if (sin->sin_addr.s_addr == INADDR_ANY) { 392 0 stevel struct in_addr v4_addr; 393 0 stevel /* 394 0 stevel * SunOS 4.x and 4.3 BSD allow an application 395 0 stevel * to connect a TCP socket to INADDR_ANY. 396 0 stevel * When they do this, the kernel picks the 397 0 stevel * address of one interface and uses it 398 0 stevel * instead. The kernel usually ends up 399 0 stevel * picking the address of the loopback 400 0 stevel * interface. This is an undocumented feature. 401 0 stevel * However, we provide the same thing here 402 0 stevel * in case any TCP apps that use this feature 403 0 stevel * are being ported to SCTP... 404 0 stevel */ 405 0 stevel v4_addr.s_addr = htonl(INADDR_LOOPBACK); 406 0 stevel IN6_INADDR_TO_V4MAPPED(&v4_addr, &dstaddr); 407 0 stevel } else { 408 0 stevel IN6_INADDR_TO_V4MAPPED(&sin->sin_addr, &dstaddr); 409 0 stevel } 410 0 stevel dstport = sin->sin_port; 411 0 stevel break; 412 0 stevel case AF_INET6: 413 0 stevel sin6 = (sin6_t *)dst; 414 0 stevel /* Check for attempt to connect to non-unicast. */ 415 0 stevel if ((addrlen < sizeof (sin6_t)) || 416 0 stevel IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 417 0 stevel ip0dbg(("sctp_connect: non-unicast\n")); 418 0 stevel return (EINVAL); 419 0 stevel } 420 11042 Erik if (connp->conn_ipv6_v6only && 421 0 stevel IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 422 0 stevel return (EAFNOSUPPORT); 423 0 stevel } 424 0 stevel /* check for attempt to connect to unspec */ 425 0 stevel if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 426 0 stevel dstaddr = ipv6_loopback; 427 0 stevel } else { 428 0 stevel dstaddr = sin6->sin6_addr; 429 11042 Erik if (IN6_IS_ADDR_LINKLOCAL(&dstaddr)) { 430 432 vi117747 sctp->sctp_linklocal = 1; 431 11042 Erik scope_id = sin6->sin6_scope_id; 432 11042 Erik } 433 0 stevel } 434 0 stevel dstport = sin6->sin6_port; 435 11042 Erik connp->conn_flowinfo = sin6->sin6_flowinfo; 436 0 stevel break; 437 0 stevel default: 438 0 stevel dprint(1, ("sctp_connect: unknown family %d\n", 439 4505 kcpoon dst->sa_family)); 440 0 stevel return (EAFNOSUPPORT); 441 0 stevel } 442 0 stevel 443 0 stevel (void) inet_ntop(AF_INET6, &dstaddr, buf, sizeof (buf)); 444 0 stevel dprint(1, ("sctp_connect: attempting connect to %s...\n", buf)); 445 0 stevel 446 0 stevel RUN_SCTP(sctp); 447 0 stevel 448 11042 Erik if (connp->conn_family != dst->sa_family || 449 11042 Erik (connp->conn_state_flags & CONN_CLOSING)) { 450 0 stevel WAKE_SCTP(sctp); 451 0 stevel return (EINVAL); 452 11042 Erik } 453 11042 Erik 454 11042 Erik /* We update our cred/cpid based on the caller of connect */ 455 11042 Erik if (connp->conn_cred != cr) { 456 11042 Erik crhold(cr); 457 11042 Erik crfree(connp->conn_cred); 458 11042 Erik connp->conn_cred = cr; 459 11042 Erik } 460 11042 Erik connp->conn_cpid = pid; 461 11042 Erik 462 11042 Erik /* Cache things in conn_ixa without any refhold */ 463 11042 Erik ixa = connp->conn_ixa; 464 11042 Erik ixa->ixa_cred = cr; 465 11042 Erik ixa->ixa_cpid = pid; 466 11042 Erik if (is_system_labeled()) { 467 11042 Erik /* We need to restart with a label based on the cred */ 468 11042 Erik ip_xmit_attr_restore_tsl(ixa, ixa->ixa_cred); 469 0 stevel } 470 0 stevel 471 0 stevel switch (sctp->sctp_state) { 472 0 stevel case SCTPS_IDLE: { 473 852 vi117747 struct sockaddr_storage ss; 474 852 vi117747 475 0 stevel /* 476 0 stevel * We support a quick connect capability here, allowing 477 0 stevel * clients to transition directly from IDLE to COOKIE_WAIT. 478 0 stevel * sctp_bindi will pick an unused port, insert the connection 479 0 stevel * in the bind hash and transition to BOUND state. SCTP 480 0 stevel * picks and uses what it considers the optimal local address 481 0 stevel * set (just like specifiying INADDR_ANY to bind()). 482 0 stevel */ 483 0 stevel dprint(1, ("sctp_connect: idle, attempting bind...\n")); 484 0 stevel ASSERT(sctp->sctp_nsaddrs == 0); 485 0 stevel 486 852 vi117747 bzero(&ss, sizeof (ss)); 487 11042 Erik ss.ss_family = connp->conn_family; 488 852 vi117747 WAKE_SCTP(sctp); 489 852 vi117747 if ((err = sctp_bind(sctp, (struct sockaddr *)&ss, 490 852 vi117747 sizeof (ss))) != 0) { 491 0 stevel return (err); 492 0 stevel } 493 852 vi117747 RUN_SCTP(sctp); 494 0 stevel /* FALLTHRU */ 495 0 stevel } 496 0 stevel 497 0 stevel case SCTPS_BOUND: 498 0 stevel ASSERT(sctp->sctp_nsaddrs > 0); 499 0 stevel 500 0 stevel /* do the connect */ 501 0 stevel /* XXX check for attempt to connect to self */ 502 11042 Erik connp->conn_fport = dstport; 503 0 stevel 504 0 stevel ASSERT(sctp->sctp_iphc); 505 0 stevel ASSERT(sctp->sctp_iphc6); 506 0 stevel 507 0 stevel /* 508 0 stevel * Don't allow this connection to completely duplicate 509 0 stevel * an existing connection. 510 0 stevel * 511 0 stevel * Ensure that the duplicate check and insertion is atomic. 512 0 stevel */ 513 0 stevel sctp_conn_hash_remove(sctp); 514 3448 dh155122 tbf = &sctps->sctps_conn_fanout[SCTP_CONN_HASH(sctps, 515 11042 Erik connp->conn_ports)]; 516 0 stevel mutex_enter(&tbf->tf_lock); 517 11042 Erik lsctp = sctp_lookup(sctp, &dstaddr, tbf, &connp->conn_ports, 518 0 stevel SCTPS_COOKIE_WAIT); 519 0 stevel if (lsctp != NULL) { 520 0 stevel /* found a duplicate connection */ 521 0 stevel mutex_exit(&tbf->tf_lock); 522 0 stevel SCTP_REFRELE(lsctp); 523 0 stevel WAKE_SCTP(sctp); 524 0 stevel return (EADDRINUSE); 525 0 stevel } 526 11042 Erik 527 0 stevel /* 528 0 stevel * OK; set up the peer addr (this may grow after we get 529 0 stevel * the INIT ACK from the peer with additional addresses). 530 0 stevel */ 531 1735 kcpoon if ((err = sctp_add_faddr(sctp, &dstaddr, sleep, 532 1735 kcpoon B_FALSE)) != 0) { 533 0 stevel mutex_exit(&tbf->tf_lock); 534 0 stevel WAKE_SCTP(sctp); 535 1676 jpk return (err); 536 0 stevel } 537 4818 kcpoon cur_fp = sctp->sctp_faddrs; 538 11042 Erik ASSERT(cur_fp->ixa != NULL); 539 4818 kcpoon 540 0 stevel /* No valid src addr, return. */ 541 4818 kcpoon if (cur_fp->state == SCTP_FADDRS_UNREACH) { 542 0 stevel mutex_exit(&tbf->tf_lock); 543 0 stevel WAKE_SCTP(sctp); 544 0 stevel return (EADDRNOTAVAIL); 545 0 stevel } 546 4818 kcpoon 547 4818 kcpoon sctp->sctp_primary = cur_fp; 548 4818 kcpoon sctp->sctp_current = cur_fp; 549 4818 kcpoon sctp->sctp_mss = cur_fp->sfa_pmss; 550 0 stevel sctp_conn_hash_insert(tbf, sctp, 1); 551 0 stevel mutex_exit(&tbf->tf_lock); 552 0 stevel 553 11042 Erik ixa = cur_fp->ixa; 554 11042 Erik ASSERT(ixa->ixa_cred != NULL); 555 11042 Erik 556 11042 Erik if (scope_id != 0) { 557 11042 Erik ixa->ixa_flags |= IXAF_SCOPEID_SET; 558 11042 Erik ixa->ixa_scopeid = scope_id; 559 11042 Erik } else { 560 11042 Erik ixa->ixa_flags &= ~IXAF_SCOPEID_SET; 561 11042 Erik } 562 11042 Erik 563 0 stevel /* initialize composite headers */ 564 1735 kcpoon if ((err = sctp_set_hdraddrs(sctp)) != 0) { 565 1676 jpk sctp_conn_hash_remove(sctp); 566 1676 jpk WAKE_SCTP(sctp); 567 1676 jpk return (err); 568 1676 jpk } 569 0 stevel 570 11042 Erik if ((err = sctp_build_hdrs(sctp, KM_SLEEP)) != 0) { 571 11042 Erik sctp_conn_hash_remove(sctp); 572 11042 Erik WAKE_SCTP(sctp); 573 11042 Erik return (err); 574 3448 dh155122 } 575 0 stevel 576 0 stevel /* 577 0 stevel * Turn off the don't fragment bit on the (only) faddr, 578 0 stevel * so that if one of the messages exchanged during the 579 0 stevel * initialization sequence exceeds the path mtu, it 580 0 stevel * at least has a chance to get there. SCTP does no 581 0 stevel * fragmentation of initialization messages. The DF bit 582 0 stevel * will be turned on again in sctp_send_cookie_echo() 583 0 stevel * (but the cookie echo will still be sent with the df bit 584 0 stevel * off). 585 0 stevel */ 586 0 stevel cur_fp->df = B_FALSE; 587 0 stevel 588 0 stevel /* Mark this address as alive */ 589 0 stevel cur_fp->state = SCTP_FADDRS_ALIVE; 590 0 stevel 591 0 stevel /* Send the INIT to the peer */ 592 0 stevel SCTP_FADDR_TIMER_RESTART(sctp, cur_fp, cur_fp->rto); 593 4818 kcpoon sctp->sctp_state = SCTPS_COOKIE_WAIT; 594 432 vi117747 /* 595 432 vi117747 * sctp_init_mp() could result in modifying the source 596 432 vi117747 * address list, so take the hash lock. 597 432 vi117747 */ 598 432 vi117747 mutex_enter(&tbf->tf_lock); 599 11042 Erik initmp = sctp_init_mp(sctp, cur_fp); 600 0 stevel if (initmp == NULL) { 601 432 vi117747 mutex_exit(&tbf->tf_lock); 602 4818 kcpoon /* 603 4818 kcpoon * It may happen that all the source addresses 604 4818 kcpoon * (loopback/link local) are removed. In that case, 605 4818 kcpoon * faile the connect. 606 4818 kcpoon */ 607 4818 kcpoon if (sctp->sctp_nsaddrs == 0) { 608 4818 kcpoon sctp_conn_hash_remove(sctp); 609 4818 kcpoon SCTP_FADDR_TIMER_STOP(cur_fp); 610 4818 kcpoon WAKE_SCTP(sctp); 611 4818 kcpoon return (EADDRNOTAVAIL); 612 4818 kcpoon } 613 4818 kcpoon 614 4818 kcpoon /* Otherwise, let the retransmission timer retry */ 615 0 stevel WAKE_SCTP(sctp); 616 4818 kcpoon goto notify_ulp; 617 0 stevel } 618 432 vi117747 mutex_exit(&tbf->tf_lock); 619 4818 kcpoon 620 852 vi117747 /* 621 852 vi117747 * On a clustered note send this notification to the clustering 622 852 vi117747 * subsystem. 623 852 vi117747 */ 624 852 vi117747 if (cl_sctp_connect != NULL) { 625 852 vi117747 uchar_t *slist; 626 852 vi117747 uchar_t *flist; 627 852 vi117747 size_t ssize; 628 852 vi117747 size_t fsize; 629 852 vi117747 630 852 vi117747 fsize = sizeof (in6_addr_t) * sctp->sctp_nfaddrs; 631 852 vi117747 ssize = sizeof (in6_addr_t) * sctp->sctp_nsaddrs; 632 852 vi117747 slist = kmem_alloc(ssize, KM_SLEEP); 633 852 vi117747 flist = kmem_alloc(fsize, KM_SLEEP); 634 852 vi117747 /* The clustering module frees the lists */ 635 852 vi117747 sctp_get_saddr_list(sctp, slist, ssize); 636 852 vi117747 sctp_get_faddr_list(sctp, flist, fsize); 637 11042 Erik (*cl_sctp_connect)(connp->conn_family, slist, 638 11042 Erik sctp->sctp_nsaddrs, connp->conn_lport, 639 11042 Erik flist, sctp->sctp_nfaddrs, connp->conn_fport, 640 852 vi117747 B_TRUE, (cl_sctp_handle_t)sctp); 641 852 vi117747 } 642 11042 Erik ASSERT(ixa->ixa_cred != NULL); 643 11042 Erik ASSERT(ixa->ixa_ire != NULL); 644 11042 Erik 645 11042 Erik (void) conn_ip_output(initmp, ixa); 646 11042 Erik BUMP_LOCAL(sctp->sctp_opkts); 647 0 stevel WAKE_SCTP(sctp); 648 0 stevel 649 4818 kcpoon notify_ulp: 650 11042 Erik sctp_set_ulp_prop(sctp); 651 0 stevel 652 0 stevel return (0); 653 0 stevel default: 654 0 stevel ip0dbg(("sctp_connect: invalid state. %d\n", sctp->sctp_state)); 655 0 stevel WAKE_SCTP(sctp); 656 0 stevel return (EINVAL); 657 0 stevel } 658 0 stevel } 659