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 10212 George * 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/strsubr.h> 32 0 stevel #include <sys/strsun.h> 33 0 stevel 34 0 stevel #include <netinet/in.h> 35 0 stevel #include <netinet/ip6.h> 36 0 stevel 37 0 stevel #include <inet/common.h> 38 0 stevel #include <inet/ip.h> 39 0 stevel #include <inet/mib2.h> 40 0 stevel #include <inet/ipclassifier.h> 41 0 stevel #include "sctp_impl.h" 42 0 stevel #include "sctp_asconf.h" 43 0 stevel 44 0 stevel /* Timer block states. */ 45 0 stevel typedef enum { 46 0 stevel SCTP_TB_RUNNING = 1, 47 0 stevel SCTP_TB_IDLE, 48 0 stevel /* Could not stop/free before mblk got queued */ 49 0 stevel SCTP_TB_RESCHED, /* sctp_tb_time_left contains tick count */ 50 0 stevel SCTP_TB_CANCELLED, 51 0 stevel SCTP_TB_TO_BE_FREED 52 0 stevel } timer_block_state; 53 0 stevel 54 0 stevel typedef struct sctp_tb_s { 55 0 stevel timer_block_state sctp_tb_state; 56 0 stevel timeout_id_t sctp_tb_tid; 57 0 stevel mblk_t *sctp_tb_mp; 58 0 stevel clock_t sctp_tb_time_left; 59 0 stevel } sctp_tb_t; 60 0 stevel 61 0 stevel static void sctp_timer_fire(sctp_tb_t *); 62 0 stevel 63 0 stevel /* 64 0 stevel * sctp_timer mechanism. 65 0 stevel * 66 0 stevel * Each timer is represented by a timer mblk. When the 67 0 stevel * timer fires, and the sctp_t is busy, the timer mblk will be put on 68 0 stevel * the associated sctp_t timer queue so that it can be executed when 69 0 stevel * the thread holding the lock on the sctp_t is done with its job. 70 0 stevel * 71 0 stevel * Note that there is no lock to protect the timer mblk state. The reason 72 0 stevel * is that the timer state can only be changed by a thread holding the 73 0 stevel * lock on the sctp_t. 74 0 stevel * 75 0 stevel * The interface consists of 4 entry points: 76 0 stevel * sctp_timer_alloc - create a timer mblk 77 0 stevel * sctp_timer_free - free a timer mblk 78 0 stevel * sctp_timer - start, restart, stop the timer 79 0 stevel * sctp_timer_valid - called by sctp_process_recvq to verify that 80 0 stevel * the timer did indeed fire. 81 0 stevel */ 82 0 stevel 83 0 stevel 84 0 stevel /* 85 0 stevel * Start, restart, stop the timer. 86 0 stevel * If "tim" is -1 the timer is stopped. 87 0 stevel * Otherwise, the timer is stopped if it is already running, and 88 0 stevel * set to fire tim clock ticks from now. 89 0 stevel */ 90 0 stevel void 91 0 stevel sctp_timer(sctp_t *sctp, mblk_t *mp, clock_t tim) 92 0 stevel { 93 0 stevel sctp_tb_t *sctp_tb; 94 0 stevel int state; 95 0 stevel 96 0 stevel ASSERT(sctp != NULL && mp != NULL); 97 0 stevel ASSERT((mp->b_rptr - mp->b_datap->db_base) == sizeof (sctp_tb_t)); 98 0 stevel ASSERT(mp->b_datap->db_type == M_PCSIG); 99 0 stevel 100 0 stevel sctp_tb = (sctp_tb_t *)mp->b_datap->db_base; 101 0 stevel if (tim >= 0) { 102 0 stevel state = sctp_tb->sctp_tb_state; 103 0 stevel sctp_tb->sctp_tb_time_left = tim; 104 0 stevel if (state == SCTP_TB_RUNNING) { 105 0 stevel if (untimeout(sctp_tb->sctp_tb_tid) < 0) { 106 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_RESCHED; 107 0 stevel /* sctp_timer_valid will start timer */ 108 0 stevel return; 109 0 stevel } 110 0 stevel } else if (state != SCTP_TB_IDLE) { 111 0 stevel ASSERT(state != SCTP_TB_TO_BE_FREED); 112 0 stevel if (state == SCTP_TB_CANCELLED) { 113 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_RESCHED; 114 0 stevel /* sctp_timer_valid will start timer */ 115 0 stevel return; 116 0 stevel } 117 0 stevel if (state == SCTP_TB_RESCHED) { 118 0 stevel /* sctp_timer_valid will start timer */ 119 0 stevel return; 120 0 stevel } 121 0 stevel } else { 122 0 stevel SCTP_REFHOLD(sctp); 123 0 stevel } 124 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_RUNNING; 125 0 stevel sctp_tb->sctp_tb_tid = 126 0 stevel timeout((pfv_t)sctp_timer_fire, sctp_tb, tim); 127 0 stevel return; 128 0 stevel } 129 0 stevel switch (tim) { 130 0 stevel case -1: 131 0 stevel sctp_timer_stop(mp); 132 0 stevel break; 133 0 stevel default: 134 0 stevel ASSERT(0); 135 0 stevel break; 136 0 stevel } 137 0 stevel } 138 0 stevel 139 0 stevel /* 140 0 stevel * sctp_timer_alloc is called by sctp_init to allocate and initialize a 141 0 stevel * sctp timer. 142 0 stevel * 143 0 stevel * Allocate an M_PCSIG timer message. The space between db_base and 144 0 stevel * b_rptr is used by the sctp_timer mechanism, and after b_rptr there is 145 0 stevel * space for sctpt_t. 146 0 stevel */ 147 0 stevel mblk_t * 148 4691 kcpoon sctp_timer_alloc(sctp_t *sctp, pfv_t func, int sleep) 149 0 stevel { 150 0 stevel mblk_t *mp; 151 0 stevel sctp_tb_t *sctp_tb; 152 0 stevel sctpt_t *sctpt; 153 3448 dh155122 sctp_stack_t *sctps = sctp->sctp_sctps; 154 0 stevel 155 4691 kcpoon if (sleep == KM_SLEEP) { 156 4691 kcpoon mp = allocb_wait(sizeof (sctp_t) + sizeof (sctp_tb_t), BPRI_HI, 157 4691 kcpoon STR_NOSIG, NULL); 158 4691 kcpoon } else { 159 4691 kcpoon mp = allocb(sizeof (sctp_t) + sizeof (sctp_tb_t), BPRI_HI); 160 4691 kcpoon } 161 4691 kcpoon if (mp != NULL) { 162 0 stevel mp->b_datap->db_type = M_PCSIG; 163 0 stevel sctp_tb = (sctp_tb_t *)mp->b_datap->db_base; 164 0 stevel mp->b_rptr = (uchar_t *)&sctp_tb[1]; 165 0 stevel mp->b_wptr = mp->b_rptr + sizeof (sctpt_t); 166 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_IDLE; 167 0 stevel sctp_tb->sctp_tb_mp = mp; 168 0 stevel 169 0 stevel sctpt = (sctpt_t *)mp->b_rptr; 170 0 stevel sctpt->sctpt_sctp = sctp; 171 0 stevel sctpt->sctpt_faddr = NULL; /* set when starting timer */ 172 0 stevel sctpt->sctpt_pfv = func; 173 0 stevel return (mp); 174 0 stevel } 175 3448 dh155122 SCTP_KSTAT(sctps, sctp_add_timer); 176 0 stevel return (NULL); 177 0 stevel } 178 0 stevel 179 0 stevel /* 180 0 stevel * timeout() callback function. 181 0 stevel * Put the message on the process control block's queue. 182 0 stevel * If the timer is stopped or freed after 183 0 stevel * it has fired then sctp_timer() and sctp_timer_valid() will clean 184 0 stevel * things up. 185 0 stevel */ 186 0 stevel static void 187 0 stevel sctp_timer_fire(sctp_tb_t *sctp_tb) 188 0 stevel { 189 0 stevel mblk_t *mp; 190 0 stevel sctp_t *sctp; 191 0 stevel sctpt_t *sctpt; 192 0 stevel 193 0 stevel mp = sctp_tb->sctp_tb_mp; 194 0 stevel ASSERT(sctp_tb == (sctp_tb_t *)mp->b_datap->db_base); 195 0 stevel ASSERT(mp->b_datap->db_type == M_PCSIG); 196 0 stevel 197 0 stevel sctpt = (sctpt_t *)mp->b_rptr; 198 0 stevel sctp = sctpt->sctpt_sctp; 199 0 stevel ASSERT(sctp != NULL); 200 0 stevel 201 0 stevel mutex_enter(&sctp->sctp_lock); 202 0 stevel if (sctp->sctp_running) { 203 0 stevel /* 204 0 stevel * Put the timer mblk to the special sctp_timer_mp list. 205 0 stevel * This timer will be handled when the thread using this 206 0 stevel * SCTP is done with its job. 207 0 stevel */ 208 0 stevel if (sctp->sctp_timer_mp == NULL) { 209 0 stevel SCTP_REFHOLD(sctp); 210 0 stevel sctp->sctp_timer_mp = mp; 211 0 stevel } else { 212 0 stevel linkb(sctp->sctp_timer_mp, mp); 213 0 stevel } 214 0 stevel mp->b_cont = NULL; 215 0 stevel mutex_exit(&sctp->sctp_lock); 216 0 stevel } else { 217 0 stevel sctp->sctp_running = B_TRUE; 218 0 stevel mutex_exit(&sctp->sctp_lock); 219 0 stevel 220 0 stevel sctp_timer_call(sctp, mp); 221 0 stevel WAKE_SCTP(sctp); 222 0 stevel } 223 0 stevel SCTP_REFRELE(sctp); 224 0 stevel } 225 0 stevel 226 0 stevel /* 227 0 stevel * Logically free a timer mblk (that might have a pending timeout().) 228 0 stevel * If the timer has fired and the mblk has been put on the queue then 229 0 stevel * sctp_timer_valid will free the mblk. 230 0 stevel */ 231 0 stevel void 232 0 stevel sctp_timer_free(mblk_t *mp) 233 0 stevel { 234 0 stevel sctp_tb_t *sctp_tb; 235 0 stevel int state; 236 0 stevel sctpt_t *sctpt; 237 0 stevel 238 0 stevel ASSERT(mp != NULL); 239 0 stevel ASSERT((mp->b_rptr - mp->b_datap->db_base) == sizeof (sctp_tb_t)); 240 0 stevel ASSERT(mp->b_datap->db_type == M_PCSIG); 241 0 stevel 242 0 stevel sctp_tb = (sctp_tb_t *)mp->b_datap->db_base; 243 0 stevel state = sctp_tb->sctp_tb_state; 244 0 stevel 245 1676 jpk dprint(5, ("sctp_timer_free %p state %d\n", (void *)mp, state)); 246 0 stevel 247 0 stevel if (state == SCTP_TB_RUNNING) { 248 0 stevel if (untimeout(sctp_tb->sctp_tb_tid) < 0) { 249 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_TO_BE_FREED; 250 0 stevel /* sctp_timer_valid will free the mblk */ 251 0 stevel return; 252 0 stevel } 253 0 stevel sctpt = (sctpt_t *)mp->b_rptr; 254 0 stevel SCTP_REFRELE(sctpt->sctpt_sctp); 255 0 stevel } else if (state != SCTP_TB_IDLE) { 256 0 stevel ASSERT(state != SCTP_TB_TO_BE_FREED); 257 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_TO_BE_FREED; 258 0 stevel /* sctp_timer_valid will free the mblk */ 259 0 stevel return; 260 0 stevel } 261 0 stevel freeb(mp); 262 0 stevel } 263 0 stevel 264 0 stevel /* 265 0 stevel * Called from sctp_timer(,,-1) 266 0 stevel */ 267 0 stevel void 268 0 stevel sctp_timer_stop(mblk_t *mp) 269 0 stevel { 270 0 stevel sctp_tb_t *sctp_tb; 271 0 stevel int state; 272 0 stevel sctpt_t *sctpt; 273 0 stevel 274 0 stevel ASSERT(mp != NULL); 275 0 stevel ASSERT(mp->b_datap->db_type == M_PCSIG); 276 0 stevel 277 0 stevel sctp_tb = (sctp_tb_t *)mp->b_datap->db_base; 278 0 stevel state = sctp_tb->sctp_tb_state; 279 0 stevel 280 1676 jpk dprint(5, ("sctp_timer_stop %p %d\n", (void *)mp, state)); 281 0 stevel 282 0 stevel if (state == SCTP_TB_RUNNING) { 283 0 stevel if (untimeout(sctp_tb->sctp_tb_tid) < 0) { 284 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_CANCELLED; 285 0 stevel } else { 286 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_IDLE; 287 0 stevel sctpt = (sctpt_t *)mp->b_rptr; 288 0 stevel SCTP_REFRELE(sctpt->sctpt_sctp); 289 0 stevel } 290 0 stevel } else if (state == SCTP_TB_RESCHED) { 291 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_CANCELLED; 292 0 stevel } 293 0 stevel } 294 0 stevel 295 0 stevel /* 296 0 stevel * The user of the sctp_timer mechanism is required to call 297 0 stevel * sctp_timer_valid() for each M_PCSIG message processed in the 298 0 stevel * service procedures. 299 0 stevel * sctp_timer_valid will return "true" if the timer actually did fire. 300 0 stevel */ 301 0 stevel 302 0 stevel static boolean_t 303 0 stevel sctp_timer_valid(mblk_t *mp) 304 0 stevel { 305 0 stevel sctp_tb_t *sctp_tb; 306 0 stevel int state; 307 0 stevel sctpt_t *sctpt; 308 0 stevel 309 0 stevel ASSERT(mp != NULL); 310 0 stevel ASSERT(mp->b_datap->db_type == M_PCSIG); 311 0 stevel 312 0 stevel sctp_tb = (sctp_tb_t *)DB_BASE(mp); 313 0 stevel sctpt = (sctpt_t *)mp->b_rptr; 314 0 stevel state = sctp_tb->sctp_tb_state; 315 0 stevel if (state != SCTP_TB_RUNNING) { 316 0 stevel ASSERT(state != SCTP_TB_IDLE); 317 0 stevel if (state == SCTP_TB_TO_BE_FREED) { 318 0 stevel /* 319 0 stevel * sctp_timer_free was called after the message 320 0 stevel * was putq'ed. 321 0 stevel */ 322 0 stevel freeb(mp); 323 0 stevel return (B_FALSE); 324 0 stevel } 325 0 stevel if (state == SCTP_TB_CANCELLED) { 326 0 stevel /* The timer was stopped after the mblk was putq'ed */ 327 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_IDLE; 328 0 stevel return (B_FALSE); 329 0 stevel } 330 0 stevel if (state == SCTP_TB_RESCHED) { 331 0 stevel /* 332 0 stevel * The timer was stopped and then restarted after 333 0 stevel * the mblk was putq'ed. 334 0 stevel * sctp_tb_time_left contains the number of ticks that 335 0 stevel * the timer was restarted with. 336 0 stevel * The sctp will not be disapper between the time 337 0 stevel * the sctpt_t is marked SCTP_TB_RESCHED and when 338 0 stevel * we get here as sctp_add_recvq() does a refhold. 339 0 stevel */ 340 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_RUNNING; 341 0 stevel sctp_tb->sctp_tb_tid = timeout((pfv_t)sctp_timer_fire, 342 0 stevel sctp_tb, sctp_tb->sctp_tb_time_left); 343 0 stevel SCTP_REFHOLD(sctpt->sctpt_sctp); 344 0 stevel return (B_FALSE); 345 0 stevel } 346 0 stevel } 347 0 stevel sctp_tb->sctp_tb_state = SCTP_TB_IDLE; 348 0 stevel return (B_TRUE); 349 0 stevel } 350 0 stevel 351 0 stevel /* 352 0 stevel * The SCTP timer call. Calls sctp_timer_valid() to verify whether 353 0 stevel * timer was cancelled or not. 354 0 stevel */ 355 0 stevel void 356 0 stevel sctp_timer_call(sctp_t *sctp, mblk_t *mp) 357 0 stevel { 358 0 stevel sctpt_t *sctpt = (sctpt_t *)mp->b_rptr; 359 0 stevel 360 0 stevel if (sctp_timer_valid(mp)) { 361 0 stevel (*sctpt->sctpt_pfv)(sctp, sctpt->sctpt_faddr); 362 0 stevel } 363 0 stevel } 364 0 stevel 365 0 stevel /* 366 0 stevel * Delayed ack 367 0 stevel */ 368 0 stevel void 369 0 stevel sctp_ack_timer(sctp_t *sctp) 370 0 stevel { 371 3448 dh155122 sctp_stack_t *sctps = sctp->sctp_sctps; 372 3448 dh155122 373 0 stevel sctp->sctp_ack_timer_running = 0; 374 3448 dh155122 sctp->sctp_sack_toggle = sctps->sctps_deferred_acks_max; 375 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpOutAckDelayed); 376 4964 kcpoon (void) sctp_sack(sctp, NULL); 377 0 stevel } 378 0 stevel 379 0 stevel /* 380 0 stevel * Peer address heartbeat timer handler 381 0 stevel */ 382 0 stevel void 383 0 stevel sctp_heartbeat_timer(sctp_t *sctp) 384 0 stevel { 385 0 stevel sctp_faddr_t *fp; 386 0 stevel int64_t now; 387 0 stevel int64_t earliest_expiry; 388 0 stevel int cnt; 389 3448 dh155122 sctp_stack_t *sctps = sctp->sctp_sctps; 390 0 stevel 391 0 stevel if (sctp->sctp_strikes >= sctp->sctp_pa_max_rxt) { 392 0 stevel /* 393 0 stevel * If there is a peer address with no strikes, 394 0 stevel * don't give up yet. If enough other peer 395 0 stevel * address are down, we could otherwise fail 396 0 stevel * the association prematurely. This is a 397 0 stevel * byproduct of our aggressive probe approach 398 0 stevel * when a heartbeat fails to connect. We may 399 0 stevel * wish to revisit this... 400 0 stevel */ 401 0 stevel if (!sctp_is_a_faddr_clean(sctp)) { 402 0 stevel /* time to give up */ 403 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpAborted); 404 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimHeartBeatDrop); 405 0 stevel sctp_assoc_event(sctp, SCTP_COMM_LOST, 0, NULL); 406 0 stevel sctp_clean_death(sctp, sctp->sctp_client_errno ? 407 0 stevel sctp->sctp_client_errno : ETIMEDOUT); 408 0 stevel return; 409 0 stevel } 410 0 stevel } 411 0 stevel 412 0 stevel /* Only send heartbeats in the established state */ 413 0 stevel if (sctp->sctp_state != SCTPS_ESTABLISHED) { 414 0 stevel dprint(5, ("sctp_heartbeat_timer: not in ESTABLISHED\n")); 415 0 stevel return; 416 0 stevel } 417 0 stevel 418 11066 rafael now = ddi_get_lbolt64(); 419 0 stevel earliest_expiry = 0; 420 3448 dh155122 cnt = sctps->sctps_maxburst; 421 0 stevel 422 0 stevel /* 423 0 stevel * Walk through all faddrs. Since the timer should run infrequently 424 0 stevel * and the number of peer addresses should not be big, this should 425 0 stevel * be OK. 426 0 stevel */ 427 0 stevel for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) { 428 0 stevel /* 429 4818 kcpoon * If the peer is unreachable because there is no available 430 11042 Erik * source address, call sctp_get_dest() to see if it is 431 4818 kcpoon * reachable now. If it is OK, the state will become 432 4818 kcpoon * unconfirmed. And the following code to handle unconfirmed 433 4818 kcpoon * address will be executed. If it is still not OK, 434 4818 kcpoon * re-schedule. If heartbeat is enabled, only try this 435 4818 kcpoon * up to the normal heartbeat max times. But if heartbeat 436 4818 kcpoon * is disable, this retry may go on forever. 437 0 stevel */ 438 4818 kcpoon if (fp->state == SCTP_FADDRS_UNREACH) { 439 11042 Erik sctp_get_dest(sctp, fp); 440 4818 kcpoon if (fp->state == SCTP_FADDRS_UNREACH) { 441 4818 kcpoon if (fp->hb_enabled && 442 4818 kcpoon ++fp->strikes > fp->max_retr && 443 4818 kcpoon sctp_faddr_dead(sctp, fp, 444 4818 kcpoon SCTP_FADDRS_DOWN) == -1) { 445 4818 kcpoon /* Assoc is dead */ 446 4818 kcpoon return; 447 4818 kcpoon } 448 4818 kcpoon fp->hb_expiry = now + SET_HB_INTVL(fp); 449 4818 kcpoon goto set_expiry; 450 4818 kcpoon } else { 451 4818 kcpoon /* Send a heartbeat immediately. */ 452 4818 kcpoon fp->hb_expiry = now; 453 4818 kcpoon } 454 4818 kcpoon } 455 4818 kcpoon /* 456 4818 kcpoon * Don't send heartbeat to this address if it is not 457 4818 kcpoon * hb_enabled and the address has been confirmed. 458 4818 kcpoon */ 459 4818 kcpoon if (!fp->hb_enabled && fp->state != SCTP_FADDRS_UNCONFIRMED) { 460 0 stevel continue; 461 0 stevel } 462 0 stevel 463 0 stevel /* 464 0 stevel * The heartbeat timer is expired. If the address is dead, 465 0 stevel * we still send heartbeat to it in case it becomes alive 466 4818 kcpoon * again. But we will only send once in a while, calculated 467 4818 kcpoon * by SET_HB_INTVL(). 468 0 stevel * 469 0 stevel * If the address is alive and there is a hearbeat pending, 470 0 stevel * resend the heartbeat and start exponential backoff on the 471 0 stevel * heartbeat timeout value. If there is no heartbeat pending, 472 0 stevel * just send out one. 473 0 stevel */ 474 0 stevel if (now >= fp->hb_expiry) { 475 0 stevel if (fp->hb_pending) { 476 0 stevel /* 477 0 stevel * If an address is not confirmed, no need 478 0 stevel * to bump the overall counter as it doesn't 479 0 stevel * matter as we will not use it to send data 480 0 stevel * and it should not affect the association. 481 0 stevel */ 482 0 stevel switch (fp->state) { 483 0 stevel case SCTP_FADDRS_ALIVE: 484 0 stevel sctp->sctp_strikes++; 485 0 stevel /* FALLTHRU */ 486 0 stevel case SCTP_FADDRS_UNCONFIRMED: 487 0 stevel /* 488 0 stevel * Retransmission implies that RTO 489 0 stevel * is probably not correct. 490 0 stevel */ 491 0 stevel fp->rtt_updates = 0; 492 0 stevel fp->strikes++; 493 0 stevel if (fp->strikes > fp->max_retr) { 494 0 stevel if (sctp_faddr_dead(sctp, fp, 495 0 stevel SCTP_FADDRS_DOWN) == -1) { 496 0 stevel /* Assoc is dead */ 497 0 stevel return; 498 0 stevel } 499 0 stevel /* 500 0 stevel * Addr is down; keep initial 501 0 stevel * RTO 502 0 stevel */ 503 0 stevel fp->rto = 504 0 stevel sctp->sctp_rto_initial; 505 0 stevel goto dead_addr; 506 0 stevel } else { 507 10212 George SCTP_CALC_RXT(sctp, fp); 508 0 stevel fp->hb_expiry = now + fp->rto; 509 0 stevel } 510 0 stevel break; 511 0 stevel case SCTP_FADDRS_DOWN: 512 0 stevel dead_addr: 513 0 stevel fp->hb_expiry = now + SET_HB_INTVL(fp); 514 0 stevel break; 515 0 stevel default: 516 0 stevel continue; 517 0 stevel } 518 0 stevel } else { 519 4818 kcpoon /* 520 4818 kcpoon * If there is unack'ed data, no need to 521 4818 kcpoon * send a heart beat. 522 4818 kcpoon */ 523 4818 kcpoon if (fp->suna > 0) { 524 4818 kcpoon fp->hb_expiry = now + SET_HB_INTVL(fp); 525 4818 kcpoon goto set_expiry; 526 4818 kcpoon } else { 527 4818 kcpoon fp->hb_expiry = now + fp->rto; 528 4818 kcpoon } 529 0 stevel } 530 0 stevel /* 531 0 stevel * Note that the total number of heartbeat we can send 532 0 stevel * out simultaneously is limited by sctp_maxburst. If 533 0 stevel * the limit is exceeded, we need to wait for the next 534 0 stevel * timeout to send them. This should only happen if 535 0 stevel * there is unconfirmed address. Note that hb_pending 536 0 stevel * is set in sctp_send_heartbeat(). So if a heartbeat 537 0 stevel * is not sent, it will not affect the state of the 538 0 stevel * peer address. 539 0 stevel */ 540 0 stevel if (fp->state != SCTP_FADDRS_UNCONFIRMED || cnt-- > 0) 541 0 stevel sctp_send_heartbeat(sctp, fp); 542 0 stevel } 543 4818 kcpoon set_expiry: 544 0 stevel if (fp->hb_expiry < earliest_expiry || earliest_expiry == 0) 545 0 stevel earliest_expiry = fp->hb_expiry; 546 0 stevel } 547 0 stevel if (sctp->sctp_autoclose != 0) { 548 0 stevel int64_t expire; 549 0 stevel 550 0 stevel expire = sctp->sctp_active + sctp->sctp_autoclose; 551 0 stevel 552 0 stevel if (expire <= now) { 553 0 stevel dprint(3, ("sctp_heartbeat_timer: autoclosing\n")); 554 0 stevel sctp_send_shutdown(sctp, 0); 555 0 stevel return; 556 0 stevel } 557 0 stevel if (expire < earliest_expiry || earliest_expiry == 0) 558 0 stevel earliest_expiry = expire; 559 0 stevel } 560 0 stevel 561 0 stevel earliest_expiry -= now; 562 0 stevel if (earliest_expiry < 0) 563 0 stevel earliest_expiry = 1; 564 0 stevel sctp_timer(sctp, sctp->sctp_heartbeat_mp, earliest_expiry); 565 0 stevel } 566 0 stevel 567 0 stevel void 568 0 stevel sctp_rexmit_timer(sctp_t *sctp, sctp_faddr_t *fp) 569 0 stevel { 570 0 stevel mblk_t *mp; 571 3448 dh155122 sctp_stack_t *sctps = sctp->sctp_sctps; 572 0 stevel 573 0 stevel ASSERT(fp != NULL); 574 0 stevel 575 0 stevel dprint(3, ("sctp_timer: faddr=%x:%x:%x:%x\n", 576 0 stevel SCTP_PRINTADDR(fp->faddr))); 577 0 stevel 578 0 stevel fp->timer_running = 0; 579 0 stevel 580 0 stevel /* Check is we've reached the max for retries */ 581 0 stevel if (sctp->sctp_state < SCTPS_ESTABLISHED) { 582 0 stevel if (fp->strikes >= sctp->sctp_max_init_rxt) { 583 0 stevel /* time to give up */ 584 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpAborted); 585 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimRetransDrop); 586 0 stevel sctp_assoc_event(sctp, SCTP_CANT_STR_ASSOC, 0, NULL); 587 0 stevel sctp_clean_death(sctp, sctp->sctp_client_errno ? 588 0 stevel sctp->sctp_client_errno : ETIMEDOUT); 589 0 stevel return; 590 0 stevel } 591 0 stevel } else if (sctp->sctp_state >= SCTPS_ESTABLISHED) { 592 0 stevel if (sctp->sctp_strikes >= sctp->sctp_pa_max_rxt) { 593 0 stevel /* time to give up */ 594 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpAborted); 595 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimRetransDrop); 596 0 stevel sctp_assoc_event(sctp, SCTP_COMM_LOST, 0, NULL); 597 0 stevel sctp_clean_death(sctp, sctp->sctp_client_errno ? 598 0 stevel sctp->sctp_client_errno : ETIMEDOUT); 599 0 stevel return; 600 0 stevel } 601 0 stevel } 602 0 stevel 603 0 stevel if (fp->strikes >= fp->max_retr) { 604 0 stevel if (sctp_faddr_dead(sctp, fp, SCTP_FADDRS_DOWN) == -1) { 605 0 stevel return; 606 0 stevel } 607 0 stevel } 608 0 stevel 609 0 stevel switch (sctp->sctp_state) { 610 4818 kcpoon case SCTPS_SHUTDOWN_RECEIVED: 611 4818 kcpoon (void) sctp_shutdown_received(sctp, NULL, B_FALSE, B_TRUE, 612 4818 kcpoon NULL); 613 0 stevel 614 0 stevel /* FALLTHRU */ 615 4818 kcpoon case SCTPS_ESTABLISHED: 616 0 stevel case SCTPS_SHUTDOWN_PENDING: 617 0 stevel if (sctp->sctp_xmit_head == NULL && 618 0 stevel sctp->sctp_xmit_unsent == NULL) { 619 0 stevel /* Nothing to retransmit */ 620 0 stevel if (sctp->sctp_state == SCTPS_SHUTDOWN_PENDING) { 621 0 stevel sctp_send_shutdown(sctp, 1); 622 0 stevel } 623 0 stevel return; 624 0 stevel } 625 0 stevel 626 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans); 627 0 stevel 628 0 stevel sctp_rexmit(sctp, fp); 629 0 stevel /* 630 0 stevel * sctp_rexmit() will increase the strikes and restart the 631 0 stevel * timer, so return here. 632 0 stevel */ 633 0 stevel return; 634 0 stevel case SCTPS_COOKIE_WAIT: 635 0 stevel BUMP_LOCAL(sctp->sctp_T1expire); 636 0 stevel rxmit_init: 637 0 stevel /* retransmit init */ 638 432 vi117747 /* 639 432 vi117747 * We don't take the conn hash lock here since the source 640 432 vi117747 * address list won't be modified (it would have been done 641 432 vi117747 * the first time around). 642 432 vi117747 */ 643 11042 Erik mp = sctp_init_mp(sctp, fp); 644 0 stevel if (mp != NULL) { 645 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans); 646 11042 Erik (void) conn_ip_output(mp, fp->ixa); 647 11042 Erik BUMP_LOCAL(sctp->sctp_opkts); 648 0 stevel } 649 0 stevel break; 650 11042 Erik case SCTPS_COOKIE_ECHOED: 651 0 stevel BUMP_LOCAL(sctp->sctp_T1expire); 652 0 stevel if (sctp->sctp_cookie_mp == NULL) { 653 0 stevel sctp->sctp_state = SCTPS_COOKIE_WAIT; 654 0 stevel goto rxmit_init; 655 0 stevel } 656 0 stevel mp = dupmsg(sctp->sctp_cookie_mp); 657 0 stevel if (mp == NULL) 658 0 stevel break; 659 11042 Erik (void) conn_ip_output(mp, fp->ixa); 660 11042 Erik BUMP_LOCAL(sctp->sctp_opkts); 661 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans); 662 0 stevel break; 663 0 stevel case SCTPS_SHUTDOWN_SENT: 664 0 stevel BUMP_LOCAL(sctp->sctp_T2expire); 665 0 stevel sctp_send_shutdown(sctp, 1); 666 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans); 667 0 stevel break; 668 0 stevel case SCTPS_SHUTDOWN_ACK_SENT: 669 0 stevel /* We shouldn't have any more outstanding data */ 670 0 stevel ASSERT(sctp->sctp_xmit_head == NULL); 671 0 stevel ASSERT(sctp->sctp_xmit_unsent == NULL); 672 0 stevel 673 0 stevel BUMP_LOCAL(sctp->sctp_T2expire); 674 1735 kcpoon (void) sctp_shutdown_received(sctp, NULL, B_FALSE, B_TRUE, 675 1735 kcpoon NULL); 676 3448 dh155122 BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans); 677 0 stevel break; 678 0 stevel default: 679 0 stevel ASSERT(0); 680 0 stevel break; 681 0 stevel } 682 0 stevel 683 0 stevel fp->strikes++; 684 0 stevel sctp->sctp_strikes++; 685 10212 George SCTP_CALC_RXT(sctp, fp); 686 0 stevel 687 0 stevel SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto); 688 0 stevel } 689 0 stevel 690 0 stevel /* 691 0 stevel * RTO calculation. timesent and now are both in ms. 692 0 stevel */ 693 0 stevel void 694 0 stevel sctp_update_rtt(sctp_t *sctp, sctp_faddr_t *fp, clock_t delta) 695 0 stevel { 696 0 stevel int rtt; 697 0 stevel 698 0 stevel /* Calculate the RTT in ms */ 699 0 stevel rtt = (int)delta; 700 0 stevel rtt = rtt > 0 ? rtt : 1; 701 0 stevel 702 1676 jpk dprint(5, ("sctp_update_rtt: fp = %p, rtt = %d\n", (void *)fp, rtt)); 703 0 stevel 704 0 stevel /* Is this the first RTT measurement? */ 705 0 stevel if (fp->srtt == -1) { 706 0 stevel fp->srtt = rtt; 707 0 stevel fp->rttvar = rtt / 2; 708 0 stevel fp->rto = 3 * rtt; /* == rtt + 4 * rttvar ( == rtt / 2) */ 709 0 stevel } else { 710 0 stevel int abs; 711 0 stevel /* 712 0 stevel * Versions of the RTO equations that use fixed-point math. 713 0 stevel * alpha and beta are NOT tunable in this implementation, 714 0 stevel * and so are hard-coded in. alpha = 1/8, beta = 1/4. 715 0 stevel */ 716 0 stevel abs = fp->srtt - rtt; 717 0 stevel abs = abs >= 0 ? abs : -abs; 718 0 stevel fp->rttvar = (3 * fp->rttvar + abs) >> 2; 719 0 stevel fp->rttvar = fp->rttvar != 0 ? fp->rttvar : 1; 720 0 stevel 721 0 stevel fp->srtt = (7 * fp->srtt + rtt) >> 3; 722 0 stevel fp->rto = fp->srtt + 4 * fp->rttvar; 723 0 stevel } 724 0 stevel 725 0 stevel dprint(5, ("sctp_update_rtt: srtt = %d, rttvar = %d, rto = %d\n", 726 0 stevel fp->srtt, fp->rttvar, fp->rto)); 727 0 stevel 728 0 stevel /* Bound the RTO by configured min and max values */ 729 0 stevel if (fp->rto < sctp->sctp_rto_min) { 730 0 stevel fp->rto = sctp->sctp_rto_min; 731 0 stevel } 732 0 stevel if (fp->rto > sctp->sctp_rto_max) { 733 0 stevel fp->rto = sctp->sctp_rto_max; 734 0 stevel } 735 0 stevel 736 10212 George SCTP_MAX_RTO(sctp, fp); 737 0 stevel fp->rtt_updates++; 738 0 stevel } 739 0 stevel 740 0 stevel void 741 0 stevel sctp_free_faddr_timers(sctp_t *sctp) 742 0 stevel { 743 0 stevel sctp_faddr_t *fp; 744 0 stevel 745 0 stevel for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) { 746 0 stevel if (fp->timer_mp != NULL) { 747 0 stevel sctp_timer_free(fp->timer_mp); 748 0 stevel fp->timer_mp = NULL; 749 0 stevel fp->timer_running = 0; 750 0 stevel } 751 0 stevel if (fp->rc_timer_mp != NULL) { 752 0 stevel sctp_timer_free(fp->rc_timer_mp); 753 0 stevel fp->rc_timer_mp = NULL; 754 0 stevel fp->rc_timer_running = 0; 755 0 stevel } 756 0 stevel } 757 0 stevel } 758 0 stevel 759 0 stevel void 760 0 stevel sctp_stop_faddr_timers(sctp_t *sctp) 761 0 stevel { 762 0 stevel sctp_faddr_t *fp; 763 0 stevel 764 0 stevel for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) { 765 0 stevel SCTP_FADDR_TIMER_STOP(fp); 766 0 stevel SCTP_FADDR_RC_TIMER_STOP(fp); 767 0 stevel } 768 0 stevel } 769 0 stevel 770 0 stevel void 771 0 stevel sctp_process_timer(sctp_t *sctp) 772 0 stevel { 773 0 stevel mblk_t *mp; 774 0 stevel 775 0 stevel ASSERT(sctp->sctp_running); 776 0 stevel ASSERT(MUTEX_HELD(&sctp->sctp_lock)); 777 0 stevel while ((mp = sctp->sctp_timer_mp) != NULL) { 778 0 stevel ASSERT(DB_TYPE(mp) == M_PCSIG); 779 0 stevel /* 780 0 stevel * Since the timer mblk can be freed in sctp_timer_call(), 781 0 stevel * we need to grab the b_cont before that. 782 0 stevel */ 783 0 stevel sctp->sctp_timer_mp = mp->b_cont; 784 0 stevel mp->b_cont = NULL; 785 7444 George /* 786 7444 George * We have a reference on the sctp, the lock must be 787 7444 George * dropped to avoid deadlocks with functions potentially 788 7444 George * called in this context which in turn call untimeout(). 789 7444 George */ 790 7444 George mutex_exit(&sctp->sctp_lock); 791 0 stevel sctp_timer_call(sctp, mp); 792 7444 George mutex_enter(&sctp->sctp_lock); 793 0 stevel } 794 0 stevel SCTP_REFRELE(sctp); 795 0 stevel } 796