sctp_timer.c revision 171572
1/*- 2 * Copyright (c) 2001-2007, by 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_timer.c,v 1.29 2005/03/06 16:04:18 itojun Exp $ */ 32 33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 171572 2007-07-24 20:06:02Z rrs $"); 35 36#define _IP_VHL 37#include <netinet/sctp_os.h> 38#include <netinet/sctp_pcb.h> 39#ifdef INET6 40#include <netinet6/sctp6_var.h> 41#endif 42#include <netinet/sctp_var.h> 43#include <netinet/sctp_sysctl.h> 44#include <netinet/sctp_timer.h> 45#include <netinet/sctputil.h> 46#include <netinet/sctp_output.h> 47#include <netinet/sctp_header.h> 48#include <netinet/sctp_indata.h> 49#include <netinet/sctp_asconf.h> 50#include <netinet/sctp_input.h> 51#include <netinet/sctp.h> 52#include <netinet/sctp_uio.h> 53 54 55 56void 57sctp_early_fr_timer(struct sctp_inpcb *inp, 58 struct sctp_tcb *stcb, 59 struct sctp_nets *net) 60{ 61 struct sctp_tmit_chunk *chk, *tp2; 62 struct timeval now, min_wait, tv; 63 unsigned int cur_rtt, cnt = 0, cnt_resend = 0; 64 65 /* an early FR is occuring. */ 66 (void)SCTP_GETTIME_TIMEVAL(&now); 67 /* get cur rto in micro-seconds */ 68 if (net->lastsa == 0) { 69 /* Hmm no rtt estimate yet? */ 70 cur_rtt = stcb->asoc.initial_rto >> 2; 71 } else { 72 73 cur_rtt = ((net->lastsa >> 2) + net->lastsv) >> 1; 74 } 75 if (cur_rtt < sctp_early_fr_msec) { 76 cur_rtt = sctp_early_fr_msec; 77 } 78 cur_rtt *= 1000; 79 tv.tv_sec = cur_rtt / 1000000; 80 tv.tv_usec = cur_rtt % 1000000; 81 min_wait = now; 82 timevalsub(&min_wait, &tv); 83 if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) { 84 /* 85 * if we hit here, we don't have enough seconds on the clock 86 * to account for the RTO. We just let the lower seconds be 87 * the bounds and don't worry about it. This may mean we 88 * will mark a lot more than we should. 89 */ 90 min_wait.tv_sec = min_wait.tv_usec = 0; 91 } 92 chk = TAILQ_LAST(&stcb->asoc.sent_queue, sctpchunk_listhead); 93 for (; chk != NULL; chk = tp2) { 94 tp2 = TAILQ_PREV(chk, sctpchunk_listhead, sctp_next); 95 if (chk->whoTo != net) { 96 continue; 97 } 98 if (chk->sent == SCTP_DATAGRAM_RESEND) 99 cnt_resend++; 100 else if ((chk->sent > SCTP_DATAGRAM_UNSENT) && 101 (chk->sent < SCTP_DATAGRAM_RESEND)) { 102 /* pending, may need retran */ 103 if (chk->sent_rcv_time.tv_sec > min_wait.tv_sec) { 104 /* 105 * we have reached a chunk that was sent 106 * some seconds past our min.. forget it we 107 * will find no more to send. 108 */ 109 continue; 110 } else if (chk->sent_rcv_time.tv_sec == min_wait.tv_sec) { 111 /* 112 * we must look at the micro seconds to 113 * know. 114 */ 115 if (chk->sent_rcv_time.tv_usec >= min_wait.tv_usec) { 116 /* 117 * ok it was sent after our boundary 118 * time. 119 */ 120 continue; 121 } 122 } 123 if (sctp_logging_level & SCTP_EARLYFR_LOGGING_ENABLE) { 124 sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count, 125 4, SCTP_FR_MARKED_EARLY); 126 } 127 SCTP_STAT_INCR(sctps_earlyfrmrkretrans); 128 chk->sent = SCTP_DATAGRAM_RESEND; 129 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 130 /* double book size since we are doing an early FR */ 131 chk->book_size_scale++; 132 cnt += chk->send_size; 133 if ((cnt + net->flight_size) > net->cwnd) { 134 /* Mark all we could possibly resend */ 135 break; 136 } 137 } 138 } 139 if (cnt) { 140 /* 141 * JRS - Use the congestion control given in the congestion 142 * control module 143 */ 144 stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer(inp, stcb, net); 145 } else if (cnt_resend) { 146 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_EARLY_FR_TMR); 147 } 148 /* Restart it? */ 149 if (net->flight_size < net->cwnd) { 150 SCTP_STAT_INCR(sctps_earlyfrstrtmr); 151 sctp_timer_start(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net); 152 } 153} 154 155void 156sctp_audit_retranmission_queue(struct sctp_association *asoc) 157{ 158 struct sctp_tmit_chunk *chk; 159 160 SCTPDBG(SCTP_DEBUG_TIMER4, "Audit invoked on send queue cnt:%d onqueue:%d\n", 161 asoc->sent_queue_retran_cnt, 162 asoc->sent_queue_cnt); 163 asoc->sent_queue_retran_cnt = 0; 164 asoc->sent_queue_cnt = 0; 165 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { 166 if (chk->sent == SCTP_DATAGRAM_RESEND) { 167 sctp_ucount_incr(asoc->sent_queue_retran_cnt); 168 } 169 asoc->sent_queue_cnt++; 170 } 171 TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) { 172 if (chk->sent == SCTP_DATAGRAM_RESEND) { 173 sctp_ucount_incr(asoc->sent_queue_retran_cnt); 174 } 175 } 176 SCTPDBG(SCTP_DEBUG_TIMER4, "Audit completes retran:%d onqueue:%d\n", 177 asoc->sent_queue_retran_cnt, 178 asoc->sent_queue_cnt); 179} 180 181int 182sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 183 struct sctp_nets *net, uint16_t threshold) 184{ 185 if (net) { 186 net->error_count++; 187 SCTPDBG(SCTP_DEBUG_TIMER4, "Error count for %p now %d thresh:%d\n", 188 net, net->error_count, 189 net->failure_threshold); 190 if (net->error_count > net->failure_threshold) { 191 /* We had a threshold failure */ 192 if (net->dest_state & SCTP_ADDR_REACHABLE) { 193 net->dest_state &= ~SCTP_ADDR_REACHABLE; 194 net->dest_state |= SCTP_ADDR_NOT_REACHABLE; 195 net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY; 196 if (net == stcb->asoc.primary_destination) { 197 net->dest_state |= SCTP_ADDR_WAS_PRIMARY; 198 } 199 /* 200 * JRS 5/14/07 - If a destination is 201 * unreachable, the PF bit is turned off. 202 * This allows an unambiguous use of the PF 203 * bit for destinations that are reachable 204 * but potentially failed. If the 205 * destination is set to the unreachable 206 * state, also set the destination to the PF 207 * state. 208 */ 209 /* 210 * Add debug message here if destination is 211 * not in PF state. 212 */ 213 /* Stop any running T3 timers here? */ 214 if (sctp_cmt_on_off && sctp_cmt_pf) { 215 net->dest_state &= ~SCTP_ADDR_PF; 216 SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n", 217 net); 218 } 219 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 220 stcb, 221 SCTP_FAILED_THRESHOLD, 222 (void *)net); 223 } 224 } 225 /*********HOLD THIS COMMENT FOR PATCH OF ALTERNATE 226 *********ROUTING CODE 227 */ 228 /*********HOLD THIS COMMENT FOR END OF PATCH OF ALTERNATE 229 *********ROUTING CODE 230 */ 231 } 232 if (stcb == NULL) 233 return (0); 234 235 if (net) { 236 if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) { 237 stcb->asoc.overall_error_count++; 238 } 239 } else { 240 stcb->asoc.overall_error_count++; 241 } 242 SCTPDBG(SCTP_DEBUG_TIMER4, "Overall error count for %p now %d thresh:%u state:%x\n", 243 &stcb->asoc, stcb->asoc.overall_error_count, 244 (uint32_t) threshold, 245 ((net == NULL) ? (uint32_t) 0 : (uint32_t) net->dest_state)); 246 /* 247 * We specifically do not do >= to give the assoc one more change 248 * before we fail it. 249 */ 250 if (stcb->asoc.overall_error_count > threshold) { 251 /* Abort notification sends a ULP notify */ 252 struct mbuf *oper; 253 254 oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), 255 0, M_DONTWAIT, 1, MT_DATA); 256 if (oper) { 257 struct sctp_paramhdr *ph; 258 uint32_t *ippp; 259 260 SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + 261 sizeof(uint32_t); 262 ph = mtod(oper, struct sctp_paramhdr *); 263 ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); 264 ph->param_length = htons(SCTP_BUF_LEN(oper)); 265 ippp = (uint32_t *) (ph + 1); 266 *ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1); 267 } 268 inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_1; 269 sctp_abort_an_association(inp, stcb, SCTP_FAILED_THRESHOLD, oper); 270 return (1); 271 } 272 return (0); 273} 274 275struct sctp_nets * 276sctp_find_alternate_net(struct sctp_tcb *stcb, 277 struct sctp_nets *net, 278 int mode) 279{ 280 /* Find and return an alternate network if possible */ 281 struct sctp_nets *alt, *mnet, *min_errors_net = NULL, *max_cwnd_net = NULL; 282 int once; 283 284 /* JRS 5/14/07 - Initialize min_errors to an impossible value. */ 285 int min_errors = -1; 286 uint32_t max_cwnd = 0; 287 288 if (stcb->asoc.numnets == 1) { 289 /* No others but net */ 290 return (TAILQ_FIRST(&stcb->asoc.nets)); 291 } 292 /* 293 * JRS 5/14/07 - If mode is set to 2, use the CMT PF find alternate 294 * net algorithm. This algorithm chooses the active destination (not 295 * in PF state) with the largest cwnd value. If all destinations are 296 * in PF state, unreachable, or unconfirmed, choose the desination 297 * that is in PF state with the lowest error count. In case of a 298 * tie, choose the destination that was most recently active. 299 */ 300 if (mode == 2) { 301 TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) { 302 /* 303 * JRS 5/14/07 - If the destination is unreachable 304 * or unconfirmed, skip it. 305 */ 306 if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) || 307 (mnet->dest_state & SCTP_ADDR_UNCONFIRMED)) { 308 continue; 309 } 310 /* 311 * JRS 5/14/07 - If the destination is reachable 312 * but in PF state, compare the error count of the 313 * destination to the minimum error count seen thus 314 * far. Store the destination with the lower error 315 * count. If the error counts are equal, store the 316 * destination that was most recently active. 317 */ 318 if (mnet->dest_state & SCTP_ADDR_PF) { 319 /* 320 * JRS 5/14/07 - If the destination under 321 * consideration is the current destination, 322 * work as if the error count is one higher. 323 * The actual error count will not be 324 * incremented until later in the t3 325 * handler. 326 */ 327 if (mnet == net) { 328 if (min_errors == -1) { 329 min_errors = mnet->error_count + 1; 330 min_errors_net = mnet; 331 } else if (mnet->error_count + 1 < min_errors) { 332 min_errors = mnet->error_count + 1; 333 min_errors_net = mnet; 334 } else if (mnet->error_count + 1 == min_errors 335 && mnet->last_active > min_errors_net->last_active) { 336 min_errors_net = mnet; 337 min_errors = mnet->error_count + 1; 338 } 339 continue; 340 } else { 341 if (min_errors == -1) { 342 min_errors = mnet->error_count; 343 min_errors_net = mnet; 344 } else if (mnet->error_count < min_errors) { 345 min_errors = mnet->error_count; 346 min_errors_net = mnet; 347 } else if (mnet->error_count == min_errors 348 && mnet->last_active > min_errors_net->last_active) { 349 min_errors_net = mnet; 350 min_errors = mnet->error_count; 351 } 352 continue; 353 } 354 } 355 /* 356 * JRS 5/14/07 - If the destination is reachable and 357 * not in PF state, compare the cwnd of the 358 * destination to the highest cwnd seen thus far. 359 * Store the destination with the higher cwnd value. 360 * If the cwnd values are equal, randomly choose one 361 * of the two destinations. 362 */ 363 if (max_cwnd < mnet->cwnd) { 364 max_cwnd_net = mnet; 365 max_cwnd = mnet->cwnd; 366 } else if (max_cwnd == mnet->cwnd) { 367 uint32_t rndval; 368 uint8_t this_random; 369 370 if (stcb->asoc.hb_random_idx > 3) { 371 rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep); 372 memcpy(stcb->asoc.hb_random_values, &rndval, sizeof(stcb->asoc.hb_random_values)); 373 this_random = stcb->asoc.hb_random_values[0]; 374 stcb->asoc.hb_random_idx++; 375 stcb->asoc.hb_ect_randombit = 0; 376 } else { 377 this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx]; 378 stcb->asoc.hb_random_idx++; 379 stcb->asoc.hb_ect_randombit = 0; 380 } 381 if (this_random % 2 == 1) { 382 max_cwnd_net = mnet; 383 max_cwnd = mnet->cwnd; 384 //Useless ? 385 } 386 } 387 } 388 /* 389 * JRS 5/14/07 - After all destination have been considered 390 * as alternates, check to see if there was some active 391 * destination (not in PF state). If not, check to see if 392 * there was some PF destination with the minimum number of 393 * errors. If not, return the original destination. If 394 * there is a min_errors_net, remove the PF flag from that 395 * destination, set the cwnd to one or two MTUs, and return 396 * the destination as an alt. If there was some active 397 * destination with a highest cwnd, return the destination 398 * as an alt. 399 */ 400 if (max_cwnd_net == NULL) { 401 if (min_errors_net == NULL) { 402 return (net); 403 } 404 min_errors_net->dest_state &= ~SCTP_ADDR_PF; 405 min_errors_net->cwnd = min_errors_net->mtu * sctp_cmt_pf; 406 if (SCTP_OS_TIMER_PENDING(&min_errors_net->rxt_timer.timer)) { 407 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, 408 stcb, min_errors_net, 409 SCTP_FROM_SCTP_TIMER + SCTP_LOC_2); 410 } 411 SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to active with %d errors.\n", 412 min_errors_net, min_errors_net->error_count); 413 return (min_errors_net); 414 } else { 415 return (max_cwnd_net); 416 } 417 } 418 /* 419 * JRS 5/14/07 - If mode is set to 1, use the CMT policy for 420 * choosing an alternate net. 421 */ 422 else if (mode == 1) { 423 TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) { 424 if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) || 425 (mnet->dest_state & SCTP_ADDR_UNCONFIRMED) 426 ) { 427 /* 428 * will skip ones that are not-reachable or 429 * unconfirmed 430 */ 431 continue; 432 } 433 if (max_cwnd < mnet->cwnd) { 434 max_cwnd_net = mnet; 435 max_cwnd = mnet->cwnd; 436 } else if (max_cwnd == mnet->cwnd) { 437 uint32_t rndval; 438 uint8_t this_random; 439 440 if (stcb->asoc.hb_random_idx > 3) { 441 rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep); 442 memcpy(stcb->asoc.hb_random_values, &rndval, 443 sizeof(stcb->asoc.hb_random_values)); 444 this_random = stcb->asoc.hb_random_values[0]; 445 stcb->asoc.hb_random_idx = 0; 446 stcb->asoc.hb_ect_randombit = 0; 447 } else { 448 this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx]; 449 stcb->asoc.hb_random_idx++; 450 stcb->asoc.hb_ect_randombit = 0; 451 } 452 if (this_random % 2) { 453 max_cwnd_net = mnet; 454 max_cwnd = mnet->cwnd; 455 } 456 } 457 } 458 if (max_cwnd_net) { 459 return (max_cwnd_net); 460 } 461 } 462 mnet = net; 463 once = 0; 464 465 if (mnet == NULL) { 466 mnet = TAILQ_FIRST(&stcb->asoc.nets); 467 } 468 do { 469 alt = TAILQ_NEXT(mnet, sctp_next); 470 if (alt == NULL) { 471 once++; 472 if (once > 1) { 473 break; 474 } 475 alt = TAILQ_FIRST(&stcb->asoc.nets); 476 } 477 if (alt->ro.ro_rt == NULL) { 478 if (alt->ro._s_addr) { 479 sctp_free_ifa(alt->ro._s_addr); 480 alt->ro._s_addr = NULL; 481 482 } 483 alt->src_addr_selected = 0; 484 } 485 if ( 486 ((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) && 487 (alt->ro.ro_rt != NULL) && 488 /* sa_ignore NO_NULL_CHK */ 489 (!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) 490 ) { 491 /* Found a reachable address */ 492 break; 493 } 494 mnet = alt; 495 } while (alt != NULL); 496 497 if (alt == NULL) { 498 /* Case where NO insv network exists (dormant state) */ 499 /* we rotate destinations */ 500 once = 0; 501 mnet = net; 502 do { 503 alt = TAILQ_NEXT(mnet, sctp_next); 504 if (alt == NULL) { 505 once++; 506 if (once > 1) { 507 break; 508 } 509 alt = TAILQ_FIRST(&stcb->asoc.nets); 510 } 511 /* sa_ignore NO_NULL_CHK */ 512 if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) && 513 (alt != net)) { 514 /* Found an alternate address */ 515 break; 516 } 517 mnet = alt; 518 } while (alt != NULL); 519 } 520 if (alt == NULL) { 521 return (net); 522 } 523 return (alt); 524} 525 526 527 528static void 529sctp_backoff_on_timeout(struct sctp_tcb *stcb, 530 struct sctp_nets *net, 531 int win_probe, 532 int num_marked) 533{ 534 if (net->RTO == 0) { 535 net->RTO = stcb->asoc.minrto; 536 } 537 net->RTO <<= 1; 538 if (net->RTO > stcb->asoc.maxrto) { 539 net->RTO = stcb->asoc.maxrto; 540 } 541 if ((win_probe == 0) && num_marked) { 542 /* We don't apply penalty to window probe scenarios */ 543 /* JRS - Use the congestion control given in the CC module */ 544 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout(stcb, net); 545 } 546} 547 548static int 549sctp_mark_all_for_resend(struct sctp_tcb *stcb, 550 struct sctp_nets *net, 551 struct sctp_nets *alt, 552 int window_probe, 553 int *num_marked) 554{ 555 556 /* 557 * Mark all chunks (well not all) that were sent to *net for 558 * retransmission. Move them to alt for there destination as well... 559 * We only mark chunks that have been outstanding long enough to 560 * have received feed-back. 561 */ 562 struct sctp_tmit_chunk *chk, *tp2, *could_be_sent = NULL; 563 struct sctp_nets *lnets; 564 struct timeval now, min_wait, tv; 565 int cur_rtt; 566 int audit_tf, num_mk, fir; 567 unsigned int cnt_mk; 568 uint32_t orig_flight, orig_tf; 569 uint32_t tsnlast, tsnfirst; 570 571 572 /* none in flight now */ 573 audit_tf = 0; 574 fir = 0; 575 /* 576 * figure out how long a data chunk must be pending before we can 577 * mark it .. 578 */ 579 (void)SCTP_GETTIME_TIMEVAL(&now); 580 /* get cur rto in micro-seconds */ 581 cur_rtt = (((net->lastsa >> 2) + net->lastsv) >> 1); 582 cur_rtt *= 1000; 583 if (sctp_logging_level & (SCTP_EARLYFR_LOGGING_ENABLE | SCTP_FR_LOGGING_ENABLE)) { 584 sctp_log_fr(cur_rtt, 585 stcb->asoc.peers_rwnd, 586 window_probe, 587 SCTP_FR_T3_MARK_TIME); 588 sctp_log_fr(net->flight_size, 589 SCTP_OS_TIMER_PENDING(&net->fr_timer.timer), 590 SCTP_OS_TIMER_ACTIVE(&net->fr_timer.timer), 591 SCTP_FR_CWND_REPORT); 592 sctp_log_fr(net->flight_size, net->cwnd, stcb->asoc.total_flight, SCTP_FR_CWND_REPORT); 593 } 594 tv.tv_sec = cur_rtt / 1000000; 595 tv.tv_usec = cur_rtt % 1000000; 596 min_wait = now; 597 timevalsub(&min_wait, &tv); 598 if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) { 599 /* 600 * if we hit here, we don't have enough seconds on the clock 601 * to account for the RTO. We just let the lower seconds be 602 * the bounds and don't worry about it. This may mean we 603 * will mark a lot more than we should. 604 */ 605 min_wait.tv_sec = min_wait.tv_usec = 0; 606 } 607 if (sctp_logging_level & (SCTP_EARLYFR_LOGGING_ENABLE | SCTP_FR_LOGGING_ENABLE)) { 608 sctp_log_fr(cur_rtt, now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME); 609 sctp_log_fr(0, min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME); 610 } 611 /* 612 * Our rwnd will be incorrect here since we are not adding back the 613 * cnt * mbuf but we will fix that down below. 614 */ 615 orig_flight = net->flight_size; 616 orig_tf = stcb->asoc.total_flight; 617 618 net->fast_retran_ip = 0; 619 /* Now on to each chunk */ 620 num_mk = cnt_mk = 0; 621 tsnfirst = tsnlast = 0; 622 chk = TAILQ_FIRST(&stcb->asoc.sent_queue); 623 for (; chk != NULL; chk = tp2) { 624 tp2 = TAILQ_NEXT(chk, sctp_next); 625 if ((compare_with_wrap(stcb->asoc.last_acked_seq, 626 chk->rec.data.TSN_seq, 627 MAX_TSN)) || 628 (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) { 629 /* Strange case our list got out of order? */ 630 SCTP_PRINTF("Our list is out of order?\n"); 631 panic("Out of order list"); 632 } 633 if ((chk->whoTo == net) && (chk->sent < SCTP_DATAGRAM_ACKED)) { 634 /* 635 * found one to mark: If it is less than 636 * DATAGRAM_ACKED it MUST not be a skipped or marked 637 * TSN but instead one that is either already set 638 * for retransmission OR one that needs 639 * retransmission. 640 */ 641 642 /* validate its been outstanding long enough */ 643 if (sctp_logging_level & (SCTP_EARLYFR_LOGGING_ENABLE | SCTP_FR_LOGGING_ENABLE)) { 644 sctp_log_fr(chk->rec.data.TSN_seq, 645 chk->sent_rcv_time.tv_sec, 646 chk->sent_rcv_time.tv_usec, 647 SCTP_FR_T3_MARK_TIME); 648 } 649 if ((chk->sent_rcv_time.tv_sec > min_wait.tv_sec) && (window_probe == 0)) { 650 /* 651 * we have reached a chunk that was sent 652 * some seconds past our min.. forget it we 653 * will find no more to send. 654 */ 655 if (sctp_logging_level & (SCTP_EARLYFR_LOGGING_ENABLE | SCTP_FR_LOGGING_ENABLE)) { 656 sctp_log_fr(0, 657 chk->sent_rcv_time.tv_sec, 658 chk->sent_rcv_time.tv_usec, 659 SCTP_FR_T3_STOPPED); 660 } 661 continue; 662 } else if ((chk->sent_rcv_time.tv_sec == min_wait.tv_sec) && 663 (window_probe == 0)) { 664 /* 665 * we must look at the micro seconds to 666 * know. 667 */ 668 if (chk->sent_rcv_time.tv_usec >= min_wait.tv_usec) { 669 /* 670 * ok it was sent after our boundary 671 * time. 672 */ 673 if (sctp_logging_level & (SCTP_EARLYFR_LOGGING_ENABLE | SCTP_FR_LOGGING_ENABLE)) { 674 sctp_log_fr(0, 675 chk->sent_rcv_time.tv_sec, 676 chk->sent_rcv_time.tv_usec, 677 SCTP_FR_T3_STOPPED); 678 } 679 continue; 680 } 681 } 682 if (PR_SCTP_TTL_ENABLED(chk->flags)) { 683 /* Is it expired? */ 684 if ((now.tv_sec > chk->rec.data.timetodrop.tv_sec) || 685 ((chk->rec.data.timetodrop.tv_sec == now.tv_sec) && 686 (now.tv_usec > chk->rec.data.timetodrop.tv_usec))) { 687 /* Yes so drop it */ 688 if (chk->data) { 689 (void)sctp_release_pr_sctp_chunk(stcb, 690 chk, 691 (SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT), 692 &stcb->asoc.sent_queue); 693 } 694 } 695 continue; 696 } 697 if (PR_SCTP_RTX_ENABLED(chk->flags)) { 698 /* Has it been retransmitted tv_sec times? */ 699 if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) { 700 if (chk->data) { 701 (void)sctp_release_pr_sctp_chunk(stcb, 702 chk, 703 (SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT), 704 &stcb->asoc.sent_queue); 705 } 706 } 707 continue; 708 } 709 if (chk->sent < SCTP_DATAGRAM_RESEND) { 710 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 711 num_mk++; 712 if (fir == 0) { 713 fir = 1; 714 tsnfirst = chk->rec.data.TSN_seq; 715 } 716 tsnlast = chk->rec.data.TSN_seq; 717 if (sctp_logging_level & (SCTP_EARLYFR_LOGGING_ENABLE | SCTP_FR_LOGGING_ENABLE)) { 718 sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count, 719 0, SCTP_FR_T3_MARKED); 720 } 721 if (chk->rec.data.chunk_was_revoked) { 722 /* deflate the cwnd */ 723 chk->whoTo->cwnd -= chk->book_size; 724 chk->rec.data.chunk_was_revoked = 0; 725 } 726 net->marked_retrans++; 727 stcb->asoc.marked_retrans++; 728 if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) { 729 sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_RSND_TO, 730 chk->whoTo->flight_size, 731 chk->book_size, 732 (uintptr_t) chk->whoTo, 733 chk->rec.data.TSN_seq); 734 } 735 sctp_flight_size_decrease(chk); 736 sctp_total_flight_decrease(stcb, chk); 737 stcb->asoc.peers_rwnd += chk->send_size; 738 stcb->asoc.peers_rwnd += sctp_peer_chunk_oh; 739 } 740 chk->sent = SCTP_DATAGRAM_RESEND; 741 SCTP_STAT_INCR(sctps_markedretrans); 742 743 /* reset the TSN for striking and other FR stuff */ 744 chk->rec.data.doing_fast_retransmit = 0; 745 /* Clear any time so NO RTT is being done */ 746 chk->do_rtt = 0; 747 if (alt != net) { 748 sctp_free_remote_addr(chk->whoTo); 749 chk->no_fr_allowed = 1; 750 chk->whoTo = alt; 751 atomic_add_int(&alt->ref_count, 1); 752 } else { 753 chk->no_fr_allowed = 0; 754 if (TAILQ_EMPTY(&stcb->asoc.send_queue)) { 755 chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq; 756 } else { 757 chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq; 758 } 759 } 760 /* 761 * CMT: Do not allow FRs on retransmitted TSNs. 762 */ 763 if (sctp_cmt_on_off == 1) { 764 chk->no_fr_allowed = 1; 765 } 766 } else if (chk->sent == SCTP_DATAGRAM_ACKED) { 767 /* remember highest acked one */ 768 could_be_sent = chk; 769 } 770 if (chk->sent == SCTP_DATAGRAM_RESEND) { 771 cnt_mk++; 772 } 773 } 774 if ((orig_flight - net->flight_size) != (orig_tf - stcb->asoc.total_flight)) { 775 /* we did not subtract the same things? */ 776 audit_tf = 1; 777 } 778 if (sctp_logging_level & (SCTP_EARLYFR_LOGGING_ENABLE | SCTP_FR_LOGGING_ENABLE)) { 779 sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT); 780 } 781#ifdef SCTP_DEBUG 782 if (num_mk) { 783 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n", 784 tsnlast); 785 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%ld\n", 786 num_mk, (u_long)stcb->asoc.peers_rwnd); 787 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n", 788 tsnlast); 789 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%d\n", 790 num_mk, 791 (int)stcb->asoc.peers_rwnd); 792 } 793#endif 794 *num_marked = num_mk; 795 if ((stcb->asoc.sent_queue_retran_cnt == 0) && (could_be_sent)) { 796 /* fix it so we retransmit the highest acked anyway */ 797 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 798 cnt_mk++; 799 could_be_sent->sent = SCTP_DATAGRAM_RESEND; 800 } 801 if (stcb->asoc.sent_queue_retran_cnt != cnt_mk) { 802#ifdef INVARIANTS 803 SCTP_PRINTF("Local Audit says there are %d for retran asoc cnt:%d we marked:%d this time\n", 804 cnt_mk, stcb->asoc.sent_queue_retran_cnt, num_mk); 805#endif 806#ifndef SCTP_AUDITING_ENABLED 807 stcb->asoc.sent_queue_retran_cnt = cnt_mk; 808#endif 809 } 810 /* Now check for a ECN Echo that may be stranded */ 811 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) { 812 if ((chk->whoTo == net) && 813 (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) { 814 sctp_free_remote_addr(chk->whoTo); 815 chk->whoTo = alt; 816 if (chk->sent != SCTP_DATAGRAM_RESEND) { 817 chk->sent = SCTP_DATAGRAM_RESEND; 818 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 819 } 820 atomic_add_int(&alt->ref_count, 1); 821 } 822 } 823 if (audit_tf) { 824 SCTPDBG(SCTP_DEBUG_TIMER4, 825 "Audit total flight due to negative value net:%p\n", 826 net); 827 stcb->asoc.total_flight = 0; 828 stcb->asoc.total_flight_count = 0; 829 /* Clear all networks flight size */ 830 TAILQ_FOREACH(lnets, &stcb->asoc.nets, sctp_next) { 831 lnets->flight_size = 0; 832 SCTPDBG(SCTP_DEBUG_TIMER4, 833 "Net:%p c-f cwnd:%d ssthresh:%d\n", 834 lnets, lnets->cwnd, lnets->ssthresh); 835 } 836 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 837 if (chk->sent < SCTP_DATAGRAM_RESEND) { 838 if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) { 839 sctp_misc_ints(SCTP_FLIGHT_LOG_UP, 840 chk->whoTo->flight_size, 841 chk->book_size, 842 (uintptr_t) chk->whoTo, 843 chk->rec.data.TSN_seq); 844 } 845 sctp_flight_size_increase(chk); 846 sctp_total_flight_increase(stcb, chk); 847 } 848 } 849 } 850 /* 851 * Setup the ecn nonce re-sync point. We do this since 852 * retranmissions are NOT setup for ECN. This means that do to 853 * Karn's rule, we don't know the total of the peers ecn bits. 854 */ 855 chk = TAILQ_FIRST(&stcb->asoc.send_queue); 856 if (chk == NULL) { 857 stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq; 858 } else { 859 stcb->asoc.nonce_resync_tsn = chk->rec.data.TSN_seq; 860 } 861 stcb->asoc.nonce_wait_for_ecne = 0; 862 stcb->asoc.nonce_sum_check = 0; 863 /* We return 1 if we only have a window probe outstanding */ 864 return (0); 865} 866 867static void 868sctp_move_all_chunks_to_alt(struct sctp_tcb *stcb, 869 struct sctp_nets *net, 870 struct sctp_nets *alt) 871{ 872 struct sctp_association *asoc; 873 struct sctp_stream_out *outs; 874 struct sctp_tmit_chunk *chk; 875 struct sctp_stream_queue_pending *sp; 876 877 if (net == alt) 878 /* nothing to do */ 879 return; 880 881 asoc = &stcb->asoc; 882 883 /* 884 * now through all the streams checking for chunks sent to our bad 885 * network. 886 */ 887 TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) { 888 /* now clean up any chunks here */ 889 TAILQ_FOREACH(sp, &outs->outqueue, next) { 890 if (sp->net == net) { 891 sctp_free_remote_addr(sp->net); 892 sp->net = alt; 893 atomic_add_int(&alt->ref_count, 1); 894 } 895 } 896 } 897 /* Now check the pending queue */ 898 TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) { 899 if (chk->whoTo == net) { 900 sctp_free_remote_addr(chk->whoTo); 901 chk->whoTo = alt; 902 atomic_add_int(&alt->ref_count, 1); 903 } 904 } 905 906} 907 908int 909sctp_t3rxt_timer(struct sctp_inpcb *inp, 910 struct sctp_tcb *stcb, 911 struct sctp_nets *net) 912{ 913 struct sctp_nets *alt; 914 int win_probe, num_mk; 915 916 if (sctp_logging_level & SCTP_FR_LOGGING_ENABLE) { 917 sctp_log_fr(0, 0, 0, SCTP_FR_T3_TIMEOUT); 918 } 919 if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { 920 struct sctp_nets *lnet; 921 922 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 923 if (net == lnet) { 924 sctp_log_cwnd(stcb, lnet, 1, SCTP_CWND_LOG_FROM_T3); 925 } else { 926 sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_LOG_FROM_T3); 927 } 928 } 929 } 930 /* Find an alternate and mark those for retransmission */ 931 if ((stcb->asoc.peers_rwnd == 0) && 932 (stcb->asoc.total_flight < net->mtu)) { 933 SCTP_STAT_INCR(sctps_timowindowprobe); 934 win_probe = 1; 935 } else { 936 win_probe = 0; 937 } 938 939 /* 940 * JRS 5/14/07 - If CMT PF is on and the destination if not already 941 * in PF state, set the destination to PF state and store the 942 * current time as the time that the destination was last active. In 943 * addition, find an alternate destination with PF-based 944 * find_alt_net(). 945 */ 946 if (sctp_cmt_on_off && sctp_cmt_pf) { 947 if ((net->dest_state & SCTP_ADDR_PF) != SCTP_ADDR_PF) { 948 net->dest_state |= SCTP_ADDR_PF; 949 net->last_active = sctp_get_tick_count(); 950 SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from active to PF.\n", 951 net); 952 } 953 alt = sctp_find_alternate_net(stcb, net, 2); 954 } else if (sctp_cmt_on_off) { 955 /* 956 * CMT: Using RTX_SSTHRESH policy for CMT. If CMT is being 957 * used, then pick dest with largest ssthresh for any 958 * retransmission. 959 */ 960 alt = net; 961 alt = sctp_find_alternate_net(stcb, alt, 1); 962 /* 963 * CUCv2: If a different dest is picked for the 964 * retransmission, then new (rtx-)pseudo_cumack needs to be 965 * tracked for orig dest. Let CUCv2 track new (rtx-) 966 * pseudo-cumack always. 967 */ 968 net->find_pseudo_cumack = 1; 969 net->find_rtx_pseudo_cumack = 1; 970 971 } else { /* CMT is OFF */ 972 alt = sctp_find_alternate_net(stcb, net, 0); 973 } 974 975 (void)sctp_mark_all_for_resend(stcb, net, alt, win_probe, &num_mk); 976 /* FR Loss recovery just ended with the T3. */ 977 stcb->asoc.fast_retran_loss_recovery = 0; 978 979 /* CMT FR loss recovery ended with the T3 */ 980 net->fast_retran_loss_recovery = 0; 981 982 /* 983 * setup the sat loss recovery that prevents satellite cwnd advance. 984 */ 985 stcb->asoc.sat_t3_loss_recovery = 1; 986 stcb->asoc.sat_t3_recovery_tsn = stcb->asoc.sending_seq; 987 988 /* Backoff the timer and cwnd */ 989 sctp_backoff_on_timeout(stcb, net, win_probe, num_mk); 990 if (win_probe == 0) { 991 /* We don't do normal threshold management on window probes */ 992 if (sctp_threshold_management(inp, stcb, net, 993 stcb->asoc.max_send_times)) { 994 /* Association was destroyed */ 995 return (1); 996 } else { 997 if (net != stcb->asoc.primary_destination) { 998 /* send a immediate HB if our RTO is stale */ 999 struct timeval now; 1000 unsigned int ms_goneby; 1001 1002 (void)SCTP_GETTIME_TIMEVAL(&now); 1003 if (net->last_sent_time.tv_sec) { 1004 ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000; 1005 } else { 1006 ms_goneby = 0; 1007 } 1008 if ((ms_goneby > net->RTO) || (net->RTO == 0)) { 1009 /* 1010 * no recent feed back in an RTO or 1011 * more, request a RTT update 1012 */ 1013 if (sctp_send_hb(stcb, 1, net) < 0) 1014 return 1; 1015 } 1016 } 1017 } 1018 } else { 1019 /* 1020 * For a window probe we don't penalize the net's but only 1021 * the association. This may fail it if SACKs are not coming 1022 * back. If sack's are coming with rwnd locked at 0, we will 1023 * continue to hold things waiting for rwnd to raise 1024 */ 1025 if (sctp_threshold_management(inp, stcb, NULL, 1026 stcb->asoc.max_send_times)) { 1027 /* Association was destroyed */ 1028 return (1); 1029 } 1030 } 1031 if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) { 1032 /* Move all pending over too */ 1033 sctp_move_all_chunks_to_alt(stcb, net, alt); 1034 1035 /* 1036 * Get the address that failed, to force a new src address 1037 * selecton and a route allocation. 1038 */ 1039 if (net->ro._s_addr) { 1040 sctp_free_ifa(net->ro._s_addr); 1041 net->ro._s_addr = NULL; 1042 } 1043 net->src_addr_selected = 0; 1044 1045 /* Force a route allocation too */ 1046 if (net->ro.ro_rt) { 1047 RTFREE(net->ro.ro_rt); 1048 net->ro.ro_rt = NULL; 1049 } 1050 /* Was it our primary? */ 1051 if ((stcb->asoc.primary_destination == net) && (alt != net)) { 1052 /* 1053 * Yes, note it as such and find an alternate note: 1054 * this means HB code must use this to resent the 1055 * primary if it goes active AND if someone does a 1056 * change-primary then this flag must be cleared 1057 * from any net structures. 1058 */ 1059 if (sctp_set_primary_addr(stcb, 1060 (struct sockaddr *)NULL, 1061 alt) == 0) { 1062 net->dest_state |= SCTP_ADDR_WAS_PRIMARY; 1063 } 1064 } 1065 } else if (sctp_cmt_on_off && sctp_cmt_pf && (net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF) { 1066 /* 1067 * JRS 5/14/07 - If the destination hasn't failed completely 1068 * but is in PF state, a PF-heartbeat needs to be sent 1069 * manually. 1070 */ 1071 if (sctp_send_hb(stcb, 1, net) < 0) 1072 return 1; 1073 } 1074 /* 1075 * Special case for cookie-echo'ed case, we don't do output but must 1076 * await the COOKIE-ACK before retransmission 1077 */ 1078 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) { 1079 /* 1080 * Here we just reset the timer and start again since we 1081 * have not established the asoc 1082 */ 1083 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net); 1084 return (0); 1085 } 1086 if (stcb->asoc.peer_supports_prsctp) { 1087 struct sctp_tmit_chunk *lchk; 1088 1089 lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc); 1090 /* C3. See if we need to send a Fwd-TSN */ 1091 if (compare_with_wrap(stcb->asoc.advanced_peer_ack_point, 1092 stcb->asoc.last_acked_seq, MAX_TSN)) { 1093 /* 1094 * ISSUE with ECN, see FWD-TSN processing for notes 1095 * on issues that will occur when the ECN NONCE 1096 * stuff is put into SCTP for cross checking. 1097 */ 1098 send_forward_tsn(stcb, &stcb->asoc); 1099 if (lchk) { 1100 /* Assure a timer is up */ 1101 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo); 1102 } 1103 } 1104 } 1105 if (sctp_logging_level & SCTP_CWND_MONITOR_ENABLE) { 1106 sctp_log_cwnd(stcb, net, net->cwnd, SCTP_CWND_LOG_FROM_RTX); 1107 } 1108 return (0); 1109} 1110 1111int 1112sctp_t1init_timer(struct sctp_inpcb *inp, 1113 struct sctp_tcb *stcb, 1114 struct sctp_nets *net) 1115{ 1116 /* bump the thresholds */ 1117 if (stcb->asoc.delayed_connection) { 1118 /* 1119 * special hook for delayed connection. The library did NOT 1120 * complete the rest of its sends. 1121 */ 1122 stcb->asoc.delayed_connection = 0; 1123 sctp_send_initiate(inp, stcb); 1124 return (0); 1125 } 1126 if (SCTP_GET_STATE((&stcb->asoc)) != SCTP_STATE_COOKIE_WAIT) { 1127 return (0); 1128 } 1129 if (sctp_threshold_management(inp, stcb, net, 1130 stcb->asoc.max_init_times)) { 1131 /* Association was destroyed */ 1132 return (1); 1133 } 1134 stcb->asoc.dropped_special_cnt = 0; 1135 sctp_backoff_on_timeout(stcb, stcb->asoc.primary_destination, 1, 0); 1136 if (stcb->asoc.initial_init_rto_max < net->RTO) { 1137 net->RTO = stcb->asoc.initial_init_rto_max; 1138 } 1139 if (stcb->asoc.numnets > 1) { 1140 /* If we have more than one addr use it */ 1141 struct sctp_nets *alt; 1142 1143 alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination, 0); 1144 if ((alt != NULL) && (alt != stcb->asoc.primary_destination)) { 1145 sctp_move_all_chunks_to_alt(stcb, stcb->asoc.primary_destination, alt); 1146 stcb->asoc.primary_destination = alt; 1147 } 1148 } 1149 /* Send out a new init */ 1150 sctp_send_initiate(inp, stcb); 1151 return (0); 1152} 1153 1154/* 1155 * For cookie and asconf we actually need to find and mark for resend, then 1156 * increment the resend counter (after all the threshold management stuff of 1157 * course). 1158 */ 1159int 1160sctp_cookie_timer(struct sctp_inpcb *inp, 1161 struct sctp_tcb *stcb, 1162 struct sctp_nets *net) 1163{ 1164 struct sctp_nets *alt; 1165 struct sctp_tmit_chunk *cookie; 1166 1167 /* first before all else we must find the cookie */ 1168 TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, sctp_next) { 1169 if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) { 1170 break; 1171 } 1172 } 1173 if (cookie == NULL) { 1174 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) { 1175 /* FOOBAR! */ 1176 struct mbuf *oper; 1177 1178 oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), 1179 0, M_DONTWAIT, 1, MT_DATA); 1180 if (oper) { 1181 struct sctp_paramhdr *ph; 1182 uint32_t *ippp; 1183 1184 SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + 1185 sizeof(uint32_t); 1186 ph = mtod(oper, struct sctp_paramhdr *); 1187 ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); 1188 ph->param_length = htons(SCTP_BUF_LEN(oper)); 1189 ippp = (uint32_t *) (ph + 1); 1190 *ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 1191 } 1192 inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_4; 1193 sctp_abort_an_association(inp, stcb, SCTP_INTERNAL_ERROR, 1194 oper); 1195 } else { 1196#ifdef INVARIANTS 1197 panic("Cookie timer expires in wrong state?"); 1198#else 1199 SCTP_PRINTF("Strange in state %d not cookie-echoed yet c-e timer expires?\n", SCTP_GET_STATE(&stcb->asoc)); 1200 return (0); 1201#endif 1202 } 1203 return (0); 1204 } 1205 /* Ok we found the cookie, threshold management next */ 1206 if (sctp_threshold_management(inp, stcb, cookie->whoTo, 1207 stcb->asoc.max_init_times)) { 1208 /* Assoc is over */ 1209 return (1); 1210 } 1211 /* 1212 * cleared theshold management now lets backoff the address & select 1213 * an alternate 1214 */ 1215 stcb->asoc.dropped_special_cnt = 0; 1216 sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0); 1217 alt = sctp_find_alternate_net(stcb, cookie->whoTo, 0); 1218 if (alt != cookie->whoTo) { 1219 sctp_free_remote_addr(cookie->whoTo); 1220 cookie->whoTo = alt; 1221 atomic_add_int(&alt->ref_count, 1); 1222 } 1223 /* Now mark the retran info */ 1224 if (cookie->sent != SCTP_DATAGRAM_RESEND) { 1225 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1226 } 1227 cookie->sent = SCTP_DATAGRAM_RESEND; 1228 /* 1229 * Now call the output routine to kick out the cookie again, Note we 1230 * don't mark any chunks for retran so that FR will need to kick in 1231 * to move these (or a send timer). 1232 */ 1233 return (0); 1234} 1235 1236int 1237sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1238 struct sctp_nets *net) 1239{ 1240 struct sctp_nets *alt; 1241 struct sctp_tmit_chunk *strrst = NULL, *chk = NULL; 1242 1243 if (stcb->asoc.stream_reset_outstanding == 0) { 1244 return (0); 1245 } 1246 /* find the existing STRRESET, we use the seq number we sent out on */ 1247 (void)sctp_find_stream_reset(stcb, stcb->asoc.str_reset_seq_out, &strrst); 1248 if (strrst == NULL) { 1249 return (0); 1250 } 1251 /* do threshold management */ 1252 if (sctp_threshold_management(inp, stcb, strrst->whoTo, 1253 stcb->asoc.max_send_times)) { 1254 /* Assoc is over */ 1255 return (1); 1256 } 1257 /* 1258 * cleared theshold management now lets backoff the address & select 1259 * an alternate 1260 */ 1261 sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0); 1262 alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0); 1263 sctp_free_remote_addr(strrst->whoTo); 1264 strrst->whoTo = alt; 1265 atomic_add_int(&alt->ref_count, 1); 1266 1267 /* See if a ECN Echo is also stranded */ 1268 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) { 1269 if ((chk->whoTo == net) && 1270 (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) { 1271 sctp_free_remote_addr(chk->whoTo); 1272 if (chk->sent != SCTP_DATAGRAM_RESEND) { 1273 chk->sent = SCTP_DATAGRAM_RESEND; 1274 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1275 } 1276 chk->whoTo = alt; 1277 atomic_add_int(&alt->ref_count, 1); 1278 } 1279 } 1280 if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) { 1281 /* 1282 * If the address went un-reachable, we need to move to 1283 * alternates for ALL chk's in queue 1284 */ 1285 sctp_move_all_chunks_to_alt(stcb, net, alt); 1286 } 1287 /* mark the retran info */ 1288 if (strrst->sent != SCTP_DATAGRAM_RESEND) 1289 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1290 strrst->sent = SCTP_DATAGRAM_RESEND; 1291 1292 /* restart the timer */ 1293 sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo); 1294 return (0); 1295} 1296 1297int 1298sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1299 struct sctp_nets *net) 1300{ 1301 struct sctp_nets *alt; 1302 struct sctp_tmit_chunk *asconf, *chk; 1303 1304 /* is this a first send, or a retransmission? */ 1305 if (stcb->asoc.asconf_sent == 0) { 1306 /* compose a new ASCONF chunk and send it */ 1307 sctp_send_asconf(stcb, net); 1308 } else { 1309 /* 1310 * Retransmission of the existing ASCONF is needed 1311 */ 1312 1313 /* find the existing ASCONF */ 1314 TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue, 1315 sctp_next) { 1316 if (asconf->rec.chunk_id.id == SCTP_ASCONF) { 1317 break; 1318 } 1319 } 1320 if (asconf == NULL) { 1321 return (0); 1322 } 1323 /* do threshold management */ 1324 if (sctp_threshold_management(inp, stcb, asconf->whoTo, 1325 stcb->asoc.max_send_times)) { 1326 /* Assoc is over */ 1327 return (1); 1328 } 1329 if (asconf->snd_count > stcb->asoc.max_send_times) { 1330 /* 1331 * Something is rotten: our peer is not responding 1332 * to ASCONFs but apparently is to other chunks. 1333 * i.e. it is not properly handling the chunk type 1334 * upper bits. Mark this peer as ASCONF incapable 1335 * and cleanup. 1336 */ 1337 SCTPDBG(SCTP_DEBUG_TIMER1, "asconf_timer: Peer has not responded to our repeated ASCONFs\n"); 1338 sctp_asconf_cleanup(stcb, net); 1339 return (0); 1340 } 1341 /* 1342 * cleared threshold management, so now backoff the net and 1343 * select an alternate 1344 */ 1345 sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0); 1346 alt = sctp_find_alternate_net(stcb, asconf->whoTo, 0); 1347 sctp_free_remote_addr(asconf->whoTo); 1348 asconf->whoTo = alt; 1349 atomic_add_int(&alt->ref_count, 1); 1350 1351 /* See if an ECN Echo is also stranded */ 1352 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) { 1353 if ((chk->whoTo == net) && 1354 (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) { 1355 sctp_free_remote_addr(chk->whoTo); 1356 chk->whoTo = alt; 1357 if (chk->sent != SCTP_DATAGRAM_RESEND) { 1358 chk->sent = SCTP_DATAGRAM_RESEND; 1359 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1360 } 1361 atomic_add_int(&alt->ref_count, 1); 1362 } 1363 } 1364 if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) { 1365 /* 1366 * If the address went un-reachable, we need to move 1367 * to the alternate for ALL chunks in queue 1368 */ 1369 sctp_move_all_chunks_to_alt(stcb, net, alt); 1370 } 1371 /* mark the retran info */ 1372 if (asconf->sent != SCTP_DATAGRAM_RESEND) 1373 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1374 asconf->sent = SCTP_DATAGRAM_RESEND; 1375 } 1376 return (0); 1377} 1378 1379/* 1380 * For the shutdown and shutdown-ack, we do not keep one around on the 1381 * control queue. This means we must generate a new one and call the general 1382 * chunk output routine, AFTER having done threshold management. 1383 */ 1384int 1385sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1386 struct sctp_nets *net) 1387{ 1388 struct sctp_nets *alt; 1389 1390 /* first threshold managment */ 1391 if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) { 1392 /* Assoc is over */ 1393 return (1); 1394 } 1395 /* second select an alternative */ 1396 alt = sctp_find_alternate_net(stcb, net, 0); 1397 1398 /* third generate a shutdown into the queue for out net */ 1399 if (alt) { 1400 sctp_send_shutdown(stcb, alt); 1401 } else { 1402 /* 1403 * if alt is NULL, there is no dest to send to?? 1404 */ 1405 return (0); 1406 } 1407 /* fourth restart timer */ 1408 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt); 1409 return (0); 1410} 1411 1412int 1413sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1414 struct sctp_nets *net) 1415{ 1416 struct sctp_nets *alt; 1417 1418 /* first threshold managment */ 1419 if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) { 1420 /* Assoc is over */ 1421 return (1); 1422 } 1423 /* second select an alternative */ 1424 alt = sctp_find_alternate_net(stcb, net, 0); 1425 1426 /* third generate a shutdown into the queue for out net */ 1427 sctp_send_shutdown_ack(stcb, alt); 1428 1429 /* fourth restart timer */ 1430 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, alt); 1431 return (0); 1432} 1433 1434static void 1435sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp, 1436 struct sctp_tcb *stcb) 1437{ 1438 struct sctp_stream_out *outs; 1439 struct sctp_stream_queue_pending *sp; 1440 unsigned int chks_in_queue = 0; 1441 int being_filled = 0; 1442 1443 /* 1444 * This function is ONLY called when the send/sent queues are empty. 1445 */ 1446 if ((stcb == NULL) || (inp == NULL)) 1447 return; 1448 1449 if (stcb->asoc.sent_queue_retran_cnt) { 1450 SCTP_PRINTF("Hmm, sent_queue_retran_cnt is non-zero %d\n", 1451 stcb->asoc.sent_queue_retran_cnt); 1452 stcb->asoc.sent_queue_retran_cnt = 0; 1453 } 1454 SCTP_TCB_SEND_LOCK(stcb); 1455 if (TAILQ_EMPTY(&stcb->asoc.out_wheel)) { 1456 int i, cnt = 0; 1457 1458 /* Check to see if a spoke fell off the wheel */ 1459 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { 1460 if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) { 1461 sctp_insert_on_wheel(stcb, &stcb->asoc, &stcb->asoc.strmout[i], 1); 1462 cnt++; 1463 } 1464 } 1465 if (cnt) { 1466 /* yep, we lost a spoke or two */ 1467 SCTP_PRINTF("Found an additional %d streams NOT on outwheel, corrected\n", cnt); 1468 } else { 1469 /* no spokes lost, */ 1470 stcb->asoc.total_output_queue_size = 0; 1471 } 1472 SCTP_TCB_SEND_UNLOCK(stcb); 1473 return; 1474 } 1475 SCTP_TCB_SEND_UNLOCK(stcb); 1476 /* Check to see if some data queued, if so report it */ 1477 TAILQ_FOREACH(outs, &stcb->asoc.out_wheel, next_spoke) { 1478 if (!TAILQ_EMPTY(&outs->outqueue)) { 1479 TAILQ_FOREACH(sp, &outs->outqueue, next) { 1480 if (sp->msg_is_complete) 1481 being_filled++; 1482 chks_in_queue++; 1483 } 1484 } 1485 } 1486 if (chks_in_queue != stcb->asoc.stream_queue_cnt) { 1487 SCTP_PRINTF("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n", 1488 stcb->asoc.stream_queue_cnt, chks_in_queue); 1489 } 1490 if (chks_in_queue) { 1491 /* call the output queue function */ 1492 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3); 1493 if ((TAILQ_EMPTY(&stcb->asoc.send_queue)) && 1494 (TAILQ_EMPTY(&stcb->asoc.sent_queue))) { 1495 /* 1496 * Probably should go in and make it go back through 1497 * and add fragments allowed 1498 */ 1499 if (being_filled == 0) { 1500 SCTP_PRINTF("Still nothing moved %d chunks are stuck\n", 1501 chks_in_queue); 1502 } 1503 } 1504 } else { 1505 SCTP_PRINTF("Found no chunks on any queue tot:%lu\n", 1506 (u_long)stcb->asoc.total_output_queue_size); 1507 stcb->asoc.total_output_queue_size = 0; 1508 } 1509} 1510 1511int 1512sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1513 struct sctp_nets *net, int cnt_of_unconf) 1514{ 1515 int ret; 1516 1517 if (net) { 1518 if (net->hb_responded == 0) { 1519 if (net->ro._s_addr) { 1520 /* 1521 * Invalidate the src address if we did not 1522 * get a response last time. 1523 */ 1524 sctp_free_ifa(net->ro._s_addr); 1525 net->ro._s_addr = NULL; 1526 net->src_addr_selected = 0; 1527 } 1528 sctp_backoff_on_timeout(stcb, net, 1, 0); 1529 } 1530 /* Zero PBA, if it needs it */ 1531 if (net->partial_bytes_acked) { 1532 net->partial_bytes_acked = 0; 1533 } 1534 } 1535 if ((stcb->asoc.total_output_queue_size > 0) && 1536 (TAILQ_EMPTY(&stcb->asoc.send_queue)) && 1537 (TAILQ_EMPTY(&stcb->asoc.sent_queue))) { 1538 sctp_audit_stream_queues_for_size(inp, stcb); 1539 } 1540 /* Send a new HB, this will do threshold managment, pick a new dest */ 1541 if (cnt_of_unconf == 0) { 1542 if (sctp_send_hb(stcb, 0, NULL) < 0) { 1543 return (1); 1544 } 1545 } else { 1546 /* 1547 * this will send out extra hb's up to maxburst if there are 1548 * any unconfirmed addresses. 1549 */ 1550 uint32_t cnt_sent = 0; 1551 1552 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 1553 if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) && 1554 (net->dest_state & SCTP_ADDR_REACHABLE)) { 1555 cnt_sent++; 1556 if (net->hb_responded == 0) { 1557 /* Did we respond last time? */ 1558 if (net->ro._s_addr) { 1559 sctp_free_ifa(net->ro._s_addr); 1560 net->ro._s_addr = NULL; 1561 net->src_addr_selected = 0; 1562 } 1563 } 1564 ret = sctp_send_hb(stcb, 1, net); 1565 if (ret < 0) 1566 return 1; 1567 else if (ret == 0) { 1568 break; 1569 } 1570 if (cnt_sent >= sctp_hb_maxburst) 1571 break; 1572 } 1573 } 1574 } 1575 return (0); 1576} 1577 1578int 1579sctp_is_hb_timer_running(struct sctp_tcb *stcb) 1580{ 1581 if (SCTP_OS_TIMER_PENDING(&stcb->asoc.hb_timer.timer)) { 1582 /* its running */ 1583 return (1); 1584 } else { 1585 /* nope */ 1586 return (0); 1587 } 1588} 1589 1590int 1591sctp_is_sack_timer_running(struct sctp_tcb *stcb) 1592{ 1593 if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) { 1594 /* its running */ 1595 return (1); 1596 } else { 1597 /* nope */ 1598 return (0); 1599 } 1600} 1601 1602#define SCTP_NUMBER_OF_MTU_SIZES 18 1603static uint32_t mtu_sizes[] = { 1604 68, 1605 296, 1606 508, 1607 512, 1608 544, 1609 576, 1610 1006, 1611 1492, 1612 1500, 1613 1536, 1614 2002, 1615 2048, 1616 4352, 1617 4464, 1618 8166, 1619 17914, 1620 32000, 1621 65535 1622}; 1623 1624 1625static uint32_t 1626sctp_getnext_mtu(struct sctp_inpcb *inp, uint32_t cur_mtu) 1627{ 1628 /* select another MTU that is just bigger than this one */ 1629 int i; 1630 1631 for (i = 0; i < SCTP_NUMBER_OF_MTU_SIZES; i++) { 1632 if (cur_mtu < mtu_sizes[i]) { 1633 /* no max_mtu is bigger than this one */ 1634 return (mtu_sizes[i]); 1635 } 1636 } 1637 /* here return the highest allowable */ 1638 return (cur_mtu); 1639} 1640 1641 1642void 1643sctp_pathmtu_timer(struct sctp_inpcb *inp, 1644 struct sctp_tcb *stcb, 1645 struct sctp_nets *net) 1646{ 1647 uint32_t next_mtu; 1648 1649 /* restart the timer in any case */ 1650 next_mtu = sctp_getnext_mtu(inp, net->mtu); 1651 if (next_mtu <= net->mtu) { 1652 /* nothing to do */ 1653 return; 1654 } { 1655 uint32_t mtu; 1656 1657 if ((net->src_addr_selected == 0) || 1658 (net->ro._s_addr == NULL) || 1659 (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) { 1660 if ((net->ro._s_addr != NULL) && (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) { 1661 sctp_free_ifa(net->ro._s_addr); 1662 net->ro._s_addr = NULL; 1663 net->src_addr_selected = 0; 1664 } else if (net->ro._s_addr == NULL) { 1665 net->ro._s_addr = sctp_source_address_selection(inp, 1666 stcb, 1667 (sctp_route_t *) & net->ro, 1668 net, 0, stcb->asoc.vrf_id); 1669 } 1670 if (net->ro._s_addr) 1671 net->src_addr_selected = 1; 1672 } 1673 if (net->ro._s_addr) { 1674 mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt); 1675 if (mtu > next_mtu) { 1676 net->mtu = next_mtu; 1677 } 1678 } 1679 } 1680 /* restart the timer */ 1681 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 1682} 1683 1684void 1685sctp_autoclose_timer(struct sctp_inpcb *inp, 1686 struct sctp_tcb *stcb, 1687 struct sctp_nets *net) 1688{ 1689 struct timeval tn, *tim_touse; 1690 struct sctp_association *asoc; 1691 int ticks_gone_by; 1692 1693 (void)SCTP_GETTIME_TIMEVAL(&tn); 1694 if (stcb->asoc.sctp_autoclose_ticks && 1695 sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) { 1696 /* Auto close is on */ 1697 asoc = &stcb->asoc; 1698 /* pick the time to use */ 1699 if (asoc->time_last_rcvd.tv_sec > 1700 asoc->time_last_sent.tv_sec) { 1701 tim_touse = &asoc->time_last_rcvd; 1702 } else { 1703 tim_touse = &asoc->time_last_sent; 1704 } 1705 /* Now has long enough transpired to autoclose? */ 1706 ticks_gone_by = SEC_TO_TICKS(tn.tv_sec - tim_touse->tv_sec); 1707 if ((ticks_gone_by > 0) && 1708 (ticks_gone_by >= (int)asoc->sctp_autoclose_ticks)) { 1709 /* 1710 * autoclose time has hit, call the output routine, 1711 * which should do nothing just to be SURE we don't 1712 * have hanging data. We can then safely check the 1713 * queues and know that we are clear to send 1714 * shutdown 1715 */ 1716 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR); 1717 /* Are we clean? */ 1718 if (TAILQ_EMPTY(&asoc->send_queue) && 1719 TAILQ_EMPTY(&asoc->sent_queue)) { 1720 /* 1721 * there is nothing queued to send, so I'm 1722 * done... 1723 */ 1724 if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) { 1725 /* only send SHUTDOWN 1st time thru */ 1726 sctp_send_shutdown(stcb, stcb->asoc.primary_destination); 1727 if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) || 1728 (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 1729 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 1730 } 1731 asoc->state = SCTP_STATE_SHUTDOWN_SENT; 1732 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 1733 stcb->sctp_ep, stcb, 1734 asoc->primary_destination); 1735 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 1736 stcb->sctp_ep, stcb, 1737 asoc->primary_destination); 1738 } 1739 } 1740 } else { 1741 /* 1742 * No auto close at this time, reset t-o to check 1743 * later 1744 */ 1745 int tmp; 1746 1747 /* fool the timer startup to use the time left */ 1748 tmp = asoc->sctp_autoclose_ticks; 1749 asoc->sctp_autoclose_ticks -= ticks_gone_by; 1750 sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, 1751 net); 1752 /* restore the real tick value */ 1753 asoc->sctp_autoclose_ticks = tmp; 1754 } 1755 } 1756} 1757 1758void 1759sctp_iterator_timer(struct sctp_iterator *it) 1760{ 1761 int iteration_count = 0; 1762 int inp_skip = 0; 1763 1764 /* 1765 * only one iterator can run at a time. This is the only way we can 1766 * cleanly pull ep's from underneath all the running interators when 1767 * a ep is freed. 1768 */ 1769 SCTP_ITERATOR_LOCK(); 1770 if (it->inp == NULL) { 1771 /* iterator is complete */ 1772done_with_iterator: 1773 SCTP_ITERATOR_UNLOCK(); 1774 SCTP_INP_INFO_WLOCK(); 1775 TAILQ_REMOVE(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr); 1776 /* stopping the callout is not needed, in theory */ 1777 SCTP_INP_INFO_WUNLOCK(); 1778 (void)SCTP_OS_TIMER_STOP(&it->tmr.timer); 1779 if (it->function_atend != NULL) { 1780 (*it->function_atend) (it->pointer, it->val); 1781 } 1782 SCTP_FREE(it, SCTP_M_ITER); 1783 return; 1784 } 1785select_a_new_ep: 1786 SCTP_INP_WLOCK(it->inp); 1787 while (((it->pcb_flags) && 1788 ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) || 1789 ((it->pcb_features) && 1790 ((it->inp->sctp_features & it->pcb_features) != it->pcb_features))) { 1791 /* endpoint flags or features don't match, so keep looking */ 1792 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { 1793 SCTP_INP_WUNLOCK(it->inp); 1794 goto done_with_iterator; 1795 } 1796 SCTP_INP_WUNLOCK(it->inp); 1797 it->inp = LIST_NEXT(it->inp, sctp_list); 1798 if (it->inp == NULL) { 1799 goto done_with_iterator; 1800 } 1801 SCTP_INP_WLOCK(it->inp); 1802 } 1803 if ((it->inp->inp_starting_point_for_iterator != NULL) && 1804 (it->inp->inp_starting_point_for_iterator != it)) { 1805 SCTP_PRINTF("Iterator collision, waiting for one at %p\n", 1806 it->inp); 1807 SCTP_INP_WUNLOCK(it->inp); 1808 goto start_timer_return; 1809 } 1810 /* mark the current iterator on the endpoint */ 1811 it->inp->inp_starting_point_for_iterator = it; 1812 SCTP_INP_WUNLOCK(it->inp); 1813 SCTP_INP_RLOCK(it->inp); 1814 /* now go through each assoc which is in the desired state */ 1815 if (it->done_current_ep == 0) { 1816 if (it->function_inp != NULL) 1817 inp_skip = (*it->function_inp) (it->inp, it->pointer, it->val); 1818 it->done_current_ep = 1; 1819 } 1820 if (it->stcb == NULL) { 1821 /* run the per instance function */ 1822 it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list); 1823 } 1824 SCTP_INP_RUNLOCK(it->inp); 1825 if ((inp_skip) || it->stcb == NULL) { 1826 if (it->function_inp_end != NULL) { 1827 inp_skip = (*it->function_inp_end) (it->inp, 1828 it->pointer, 1829 it->val); 1830 } 1831 goto no_stcb; 1832 } 1833 if ((it->stcb) && 1834 (it->stcb->asoc.stcb_starting_point_for_iterator == it)) { 1835 it->stcb->asoc.stcb_starting_point_for_iterator = NULL; 1836 } 1837 while (it->stcb) { 1838 SCTP_TCB_LOCK(it->stcb); 1839 if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) { 1840 /* not in the right state... keep looking */ 1841 SCTP_TCB_UNLOCK(it->stcb); 1842 goto next_assoc; 1843 } 1844 /* mark the current iterator on the assoc */ 1845 it->stcb->asoc.stcb_starting_point_for_iterator = it; 1846 /* see if we have limited out the iterator loop */ 1847 iteration_count++; 1848 if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) { 1849 start_timer_return: 1850 /* set a timer to continue this later */ 1851 if (it->stcb) 1852 SCTP_TCB_UNLOCK(it->stcb); 1853 sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, 1854 (struct sctp_inpcb *)it, NULL, NULL); 1855 SCTP_ITERATOR_UNLOCK(); 1856 return; 1857 } 1858 /* run function on this one */ 1859 (*it->function_assoc) (it->inp, it->stcb, it->pointer, it->val); 1860 1861 /* 1862 * we lie here, it really needs to have its own type but 1863 * first I must verify that this won't effect things :-0 1864 */ 1865 if (it->no_chunk_output == 0) 1866 sctp_chunk_output(it->inp, it->stcb, SCTP_OUTPUT_FROM_T3); 1867 1868 SCTP_TCB_UNLOCK(it->stcb); 1869next_assoc: 1870 it->stcb = LIST_NEXT(it->stcb, sctp_tcblist); 1871 if (it->stcb == NULL) { 1872 if (it->function_inp_end != NULL) { 1873 inp_skip = (*it->function_inp_end) (it->inp, 1874 it->pointer, 1875 it->val); 1876 } 1877 } 1878 } 1879no_stcb: 1880 /* done with all assocs on this endpoint, move on to next endpoint */ 1881 it->done_current_ep = 0; 1882 SCTP_INP_WLOCK(it->inp); 1883 it->inp->inp_starting_point_for_iterator = NULL; 1884 SCTP_INP_WUNLOCK(it->inp); 1885 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { 1886 it->inp = NULL; 1887 } else { 1888 SCTP_INP_INFO_RLOCK(); 1889 it->inp = LIST_NEXT(it->inp, sctp_list); 1890 SCTP_INP_INFO_RUNLOCK(); 1891 } 1892 if (it->inp == NULL) { 1893 goto done_with_iterator; 1894 } 1895 goto select_a_new_ep; 1896} 1897