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