1 /*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * a) Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * b) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the distribution.
15 *
16 * c) Neither the name of Cisco Systems, Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD: releng/9.1/sys/netinet/sctp_timer.c 237896 2012-07-01 07:59:00Z tuexen $");
35
36 #define _IP_VHL
37 #include <netinet/sctp_os.h>
38 #include <netinet/sctp_pcb.h>
39 #ifdef INET6
40 #endif
41 #include <netinet/sctp_var.h>
42 #include <netinet/sctp_sysctl.h>
43 #include <netinet/sctp_timer.h>
44 #include <netinet/sctputil.h>
45 #include <netinet/sctp_output.h>
46 #include <netinet/sctp_header.h>
47 #include <netinet/sctp_indata.h>
48 #include <netinet/sctp_asconf.h>
49 #include <netinet/sctp_input.h>
50 #include <netinet/sctp.h>
51 #include <netinet/sctp_uio.h>
52 #include <netinet/udp.h>
53
54
55 void
56 sctp_audit_retranmission_queue(struct sctp_association *asoc)
57 {
58 struct sctp_tmit_chunk *chk;
59
60 SCTPDBG(SCTP_DEBUG_TIMER4, "Audit invoked on send queue cnt:%d onqueue:%d\n",
61 asoc->sent_queue_retran_cnt,
62 asoc->sent_queue_cnt);
63 asoc->sent_queue_retran_cnt = 0;
64 asoc->sent_queue_cnt = 0;
65 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
66 if (chk->sent == SCTP_DATAGRAM_RESEND) {
67 sctp_ucount_incr(asoc->sent_queue_retran_cnt);
68 }
69 asoc->sent_queue_cnt++;
70 }
71 TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
72 if (chk->sent == SCTP_DATAGRAM_RESEND) {
73 sctp_ucount_incr(asoc->sent_queue_retran_cnt);
74 }
75 }
76 TAILQ_FOREACH(chk, &asoc->asconf_send_queue, sctp_next) {
77 if (chk->sent == SCTP_DATAGRAM_RESEND) {
78 sctp_ucount_incr(asoc->sent_queue_retran_cnt);
79 }
80 }
81 SCTPDBG(SCTP_DEBUG_TIMER4, "Audit completes retran:%d onqueue:%d\n",
82 asoc->sent_queue_retran_cnt,
83 asoc->sent_queue_cnt);
84 }
85
86 int
87 sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
88 struct sctp_nets *net, uint16_t threshold)
89 {
90 if (net) {
91 net->error_count++;
92 SCTPDBG(SCTP_DEBUG_TIMER4, "Error count for %p now %d thresh:%d\n",
93 net, net->error_count,
94 net->failure_threshold);
95 if (net->error_count > net->failure_threshold) {
96 /* We had a threshold failure */
97 if (net->dest_state & SCTP_ADDR_REACHABLE) {
98 net->dest_state &= ~SCTP_ADDR_REACHABLE;
99 net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
100 net->dest_state &= ~SCTP_ADDR_PF;
101 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
102 stcb, 0,
103 (void *)net, SCTP_SO_NOT_LOCKED);
104 }
105 } else if ((net->pf_threshold < net->failure_threshold) &&
106 (net->error_count > net->pf_threshold)) {
107 if (!(net->dest_state & SCTP_ADDR_PF)) {
108 net->dest_state |= SCTP_ADDR_PF;
109 net->last_active = sctp_get_tick_count();
110 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
111 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
112 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
113 }
114 }
115 }
116 if (stcb == NULL)
117 return (0);
118
119 if (net) {
120 if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
121 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
122 sctp_misc_ints(SCTP_THRESHOLD_INCR,
123 stcb->asoc.overall_error_count,
124 (stcb->asoc.overall_error_count + 1),
125 SCTP_FROM_SCTP_TIMER,
126 __LINE__);
127 }
128 stcb->asoc.overall_error_count++;
129 }
130 } else {
131 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
132 sctp_misc_ints(SCTP_THRESHOLD_INCR,
133 stcb->asoc.overall_error_count,
134 (stcb->asoc.overall_error_count + 1),
135 SCTP_FROM_SCTP_TIMER,
136 __LINE__);
137 }
138 stcb->asoc.overall_error_count++;
139 }
140 SCTPDBG(SCTP_DEBUG_TIMER4, "Overall error count for %p now %d thresh:%u state:%x\n",
141 &stcb->asoc, stcb->asoc.overall_error_count,
142 (uint32_t) threshold,
143 ((net == NULL) ? (uint32_t) 0 : (uint32_t) net->dest_state));
144 /*
145 * We specifically do not do >= to give the assoc one more change
146 * before we fail it.
147 */
148 if (stcb->asoc.overall_error_count > threshold) {
149 /* Abort notification sends a ULP notify */
150 struct mbuf *oper;
151
152 oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
153 0, M_DONTWAIT, 1, MT_DATA);
154 if (oper) {
155 struct sctp_paramhdr *ph;
156 uint32_t *ippp;
157
158 SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
159 sizeof(uint32_t);
160 ph = mtod(oper, struct sctp_paramhdr *);
161 ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
162 ph->param_length = htons(SCTP_BUF_LEN(oper));
163 ippp = (uint32_t *) (ph + 1);
164 *ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
165 }
166 inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_1;
167 sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
168 return (1);
169 }
170 return (0);
171 }
172
173 /*
174 * sctp_find_alternate_net() returns a non-NULL pointer as long
175 * the argument net is non-NULL.
176 */
177 struct sctp_nets *
178 sctp_find_alternate_net(struct sctp_tcb *stcb,
179 struct sctp_nets *net,
180 int mode)
181 {
182 /* Find and return an alternate network if possible */
183 struct sctp_nets *alt, *mnet, *min_errors_net = NULL, *max_cwnd_net = NULL;
184 int once;
185
186 /* JRS 5/14/07 - Initialize min_errors to an impossible value. */
187 int min_errors = -1;
188 uint32_t max_cwnd = 0;
189
190 if (stcb->asoc.numnets == 1) {
191 /* No others but net */
192 return (TAILQ_FIRST(&stcb->asoc.nets));
193 }
194 /*
195 * JRS 5/14/07 - If mode is set to 2, use the CMT PF find alternate
196 * net algorithm. This algorithm chooses the active destination (not
197 * in PF state) with the largest cwnd value. If all destinations are
198 * in PF state, unreachable, or unconfirmed, choose the desination
199 * that is in PF state with the lowest error count. In case of a
200 * tie, choose the destination that was most recently active.
201 */
202 if (mode == 2) {
203 TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
204 /*
205 * JRS 5/14/07 - If the destination is unreachable
206 * or unconfirmed, skip it.
207 */
208 if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
209 (mnet->dest_state & SCTP_ADDR_UNCONFIRMED)) {
210 continue;
211 }
212 /*
213 * JRS 5/14/07 - If the destination is reachable
214 * but in PF state, compare the error count of the
215 * destination to the minimum error count seen thus
216 * far. Store the destination with the lower error
217 * count. If the error counts are equal, store the
218 * destination that was most recently active.
219 */
220 if (mnet->dest_state & SCTP_ADDR_PF) {
221 /*
222 * JRS 5/14/07 - If the destination under
223 * consideration is the current destination,
224 * work as if the error count is one higher.
225 * The actual error count will not be
226 * incremented until later in the t3
227 * handler.
228 */
229 if (mnet == net) {
230 if (min_errors == -1) {
231 min_errors = mnet->error_count + 1;
232 min_errors_net = mnet;
233 } else if (mnet->error_count + 1 < min_errors) {
234 min_errors = mnet->error_count + 1;
235 min_errors_net = mnet;
236 } else if (mnet->error_count + 1 == min_errors
237 && mnet->last_active > min_errors_net->last_active) {
238 min_errors_net = mnet;
239 min_errors = mnet->error_count + 1;
240 }
241 continue;
242 } else {
243 if (min_errors == -1) {
244 min_errors = mnet->error_count;
245 min_errors_net = mnet;
246 } else if (mnet->error_count < min_errors) {
247 min_errors = mnet->error_count;
248 min_errors_net = mnet;
249 } else if (mnet->error_count == min_errors
250 && mnet->last_active > min_errors_net->last_active) {
251 min_errors_net = mnet;
252 min_errors = mnet->error_count;
253 }
254 continue;
255 }
256 }
257 /*
258 * JRS 5/14/07 - If the destination is reachable and
259 * not in PF state, compare the cwnd of the
260 * destination to the highest cwnd seen thus far.
261 * Store the destination with the higher cwnd value.
262 * If the cwnd values are equal, randomly choose one
263 * of the two destinations.
264 */
265 if (max_cwnd < mnet->cwnd) {
266 max_cwnd_net = mnet;
267 max_cwnd = mnet->cwnd;
268 } else if (max_cwnd == mnet->cwnd) {
269 uint32_t rndval;
270 uint8_t this_random;
271
272 if (stcb->asoc.hb_random_idx > 3) {
273 rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep);
274 memcpy(stcb->asoc.hb_random_values, &rndval, sizeof(stcb->asoc.hb_random_values));
275 this_random = stcb->asoc.hb_random_values[0];
276 stcb->asoc.hb_random_idx++;
277 stcb->asoc.hb_ect_randombit = 0;
278 } else {
279 this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
280 stcb->asoc.hb_random_idx++;
281 stcb->asoc.hb_ect_randombit = 0;
282 }
283 if (this_random % 2 == 1) {
284 max_cwnd_net = mnet;
285 max_cwnd = mnet->cwnd; /* Useless? */
286 }
287 }
288 }
289 if (max_cwnd_net == NULL) {
290 if (min_errors_net == NULL) {
291 return (net);
292 }
293 return (min_errors_net);
294 } else {
295 return (max_cwnd_net);
296 }
297 }
298 /*
299 * JRS 5/14/07 - If mode is set to 1, use the CMT policy for
300 * choosing an alternate net.
301 */
302 else if (mode == 1) {
303 TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
304 if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
305 (mnet->dest_state & SCTP_ADDR_UNCONFIRMED)) {
306 /*
307 * will skip ones that are not-reachable or
308 * unconfirmed
309 */
310 continue;
311 }
312 if (max_cwnd < mnet->cwnd) {
313 max_cwnd_net = mnet;
314 max_cwnd = mnet->cwnd;
315 } else if (max_cwnd == mnet->cwnd) {
316 uint32_t rndval;
317 uint8_t this_random;
318
319 if (stcb->asoc.hb_random_idx > 3) {
320 rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep);
321 memcpy(stcb->asoc.hb_random_values, &rndval,
322 sizeof(stcb->asoc.hb_random_values));
323 this_random = stcb->asoc.hb_random_values[0];
324 stcb->asoc.hb_random_idx = 0;
325 stcb->asoc.hb_ect_randombit = 0;
326 } else {
327 this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
328 stcb->asoc.hb_random_idx++;
329 stcb->asoc.hb_ect_randombit = 0;
330 }
331 if (this_random % 2) {
332 max_cwnd_net = mnet;
333 max_cwnd = mnet->cwnd;
334 }
335 }
336 }
337 if (max_cwnd_net) {
338 return (max_cwnd_net);
339 }
340 }
341 mnet = net;
342 once = 0;
343
344 if (mnet == NULL) {
345 mnet = TAILQ_FIRST(&stcb->asoc.nets);
346 if (mnet == NULL) {
347 return (NULL);
348 }
349 }
350 do {
351 alt = TAILQ_NEXT(mnet, sctp_next);
352 if (alt == NULL) {
353 once++;
354 if (once > 1) {
355 break;
356 }
357 alt = TAILQ_FIRST(&stcb->asoc.nets);
358 if (alt == NULL) {
359 return (NULL);
360 }
361 }
362 if (alt->ro.ro_rt == NULL) {
363 if (alt->ro._s_addr) {
364 sctp_free_ifa(alt->ro._s_addr);
365 alt->ro._s_addr = NULL;
366 }
367 alt->src_addr_selected = 0;
368 }
369 /* sa_ignore NO_NULL_CHK */
370 if (((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
371 (alt->ro.ro_rt != NULL) &&
372 (!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))) {
373 /* Found a reachable address */
374 break;
375 }
376 mnet = alt;
377 } while (alt != NULL);
378
379 if (alt == NULL) {
380 /* Case where NO insv network exists (dormant state) */
381 /* we rotate destinations */
382 once = 0;
383 mnet = net;
384 do {
385 if (mnet == NULL) {
386 return (TAILQ_FIRST(&stcb->asoc.nets));
387 }
388 alt = TAILQ_NEXT(mnet, sctp_next);
389 if (alt == NULL) {
390 once++;
391 if (once > 1) {
392 break;
393 }
394 alt = TAILQ_FIRST(&stcb->asoc.nets);
395 }
396 /* sa_ignore NO_NULL_CHK */
397 if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
398 (alt != net)) {
399 /* Found an alternate address */
400 break;
401 }
402 mnet = alt;
403 } while (alt != NULL);
404 }
405 if (alt == NULL) {
406 return (net);
407 }
408 return (alt);
409 }
410
411 static void
412 sctp_backoff_on_timeout(struct sctp_tcb *stcb,
413 struct sctp_nets *net,
414 int win_probe,
415 int num_marked, int num_abandoned)
416 {
417 if (net->RTO == 0) {
418 net->RTO = stcb->asoc.minrto;
419 }
420 net->RTO <<= 1;
421 if (net->RTO > stcb->asoc.maxrto) {
422 net->RTO = stcb->asoc.maxrto;
423 }
424 if ((win_probe == 0) && (num_marked || num_abandoned)) {
425 /* We don't apply penalty to window probe scenarios */
426 /* JRS - Use the congestion control given in the CC module */
427 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout(stcb, net);
428 }
429 }
430
431 #ifndef INVARIANTS
432 static void
433 sctp_recover_sent_list(struct sctp_tcb *stcb)
434 {
435 struct sctp_tmit_chunk *chk, *nchk;
436 struct sctp_association *asoc;
437
438 asoc = &stcb->asoc;
439 TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
440 if (SCTP_TSN_GE(asoc->last_acked_seq, chk->rec.data.TSN_seq)) {
441 SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n",
442 chk, chk->rec.data.TSN_seq, asoc->last_acked_seq);
443 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
444 if (chk->pr_sctp_on) {
445 if (asoc->pr_sctp_cnt != 0)
446 asoc->pr_sctp_cnt--;
447 }
448 if (chk->data) {
449 /* sa_ignore NO_NULL_CHK */
450 sctp_free_bufspace(stcb, asoc, chk, 1);
451 sctp_m_freem(chk->data);
452 chk->data = NULL;
453 if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) {
454 asoc->sent_queue_cnt_removeable--;
455 }
456 }
457 asoc->sent_queue_cnt--;
458 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
459 }
460 }
461 SCTP_PRINTF("after recover order is as follows\n");
462 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
463 SCTP_PRINTF("chk:%p TSN:%x\n", chk, chk->rec.data.TSN_seq);
464 }
465 }
466
467 #endif
468
469 static int
470 sctp_mark_all_for_resend(struct sctp_tcb *stcb,
471 struct sctp_nets *net,
472 struct sctp_nets *alt,
473 int window_probe,
474 int *num_marked,
475 int *num_abandoned)
476 {
477
478 /*
479 * Mark all chunks (well not all) that were sent to *net for
480 * retransmission. Move them to alt for there destination as well...
481 * We only mark chunks that have been outstanding long enough to
482 * have received feed-back.
483 */
484 struct sctp_tmit_chunk *chk, *nchk;
485 struct sctp_nets *lnets;
486 struct timeval now, min_wait, tv;
487 int cur_rto;
488 int cnt_abandoned;
489 int audit_tf, num_mk, fir;
490 unsigned int cnt_mk;
491 uint32_t orig_flight, orig_tf;
492 uint32_t tsnlast, tsnfirst;
493 int recovery_cnt = 0;
494
495
496 /* none in flight now */
497 audit_tf = 0;
498 fir = 0;
499 /*
500 * figure out how long a data chunk must be pending before we can
501 * mark it ..
502 */
503 (void)SCTP_GETTIME_TIMEVAL(&now);
504 /* get cur rto in micro-seconds */
505 cur_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
506 cur_rto *= 1000;
507 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
508 sctp_log_fr(cur_rto,
509 stcb->asoc.peers_rwnd,
510 window_probe,
511 SCTP_FR_T3_MARK_TIME);
512 sctp_log_fr(net->flight_size, 0, 0, SCTP_FR_CWND_REPORT);
513 sctp_log_fr(net->flight_size, net->cwnd, stcb->asoc.total_flight, SCTP_FR_CWND_REPORT);
514 }
515 tv.tv_sec = cur_rto / 1000000;
516 tv.tv_usec = cur_rto % 1000000;
517 min_wait = now;
518 timevalsub(&min_wait, &tv);
519 if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) {
520 /*
521 * if we hit here, we don't have enough seconds on the clock
522 * to account for the RTO. We just let the lower seconds be
523 * the bounds and don't worry about it. This may mean we
524 * will mark a lot more than we should.
525 */
526 min_wait.tv_sec = min_wait.tv_usec = 0;
527 }
528 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
529 sctp_log_fr(cur_rto, now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME);
530 sctp_log_fr(0, min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME);
531 }
532 /*
533 * Our rwnd will be incorrect here since we are not adding back the
534 * cnt * mbuf but we will fix that down below.
535 */
536 orig_flight = net->flight_size;
537 orig_tf = stcb->asoc.total_flight;
538
539 net->fast_retran_ip = 0;
540 /* Now on to each chunk */
541 cnt_abandoned = 0;
542 num_mk = cnt_mk = 0;
543 tsnfirst = tsnlast = 0;
544 #ifndef INVARIANTS
545 start_again:
546 #endif
547 TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) {
548 if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) {
549 /* Strange case our list got out of order? */
550 SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x",
551 (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq);
552 recovery_cnt++;
553 #ifdef INVARIANTS
554 panic("last acked >= chk on sent-Q");
555 #else
556 SCTP_PRINTF("Recover attempts a restart cnt:%d\n", recovery_cnt);
557 sctp_recover_sent_list(stcb);
558 if (recovery_cnt < 10) {
559 goto start_again;
560 } else {
561 SCTP_PRINTF("Recovery fails %d times??\n", recovery_cnt);
562 }
563 #endif
564 }
565 if ((chk->whoTo == net) && (chk->sent < SCTP_DATAGRAM_ACKED)) {
566 /*
567 * found one to mark: If it is less than
568 * DATAGRAM_ACKED it MUST not be a skipped or marked
569 * TSN but instead one that is either already set
570 * for retransmission OR one that needs
571 * retransmission.
572 */
573
574 /* validate its been outstanding long enough */
575 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
576 sctp_log_fr(chk->rec.data.TSN_seq,
577 chk->sent_rcv_time.tv_sec,
578 chk->sent_rcv_time.tv_usec,
579 SCTP_FR_T3_MARK_TIME);
580 }
581 if ((chk->sent_rcv_time.tv_sec > min_wait.tv_sec) && (window_probe == 0)) {
582 /*
583 * we have reached a chunk that was sent
584 * some seconds past our min.. forget it we
585 * will find no more to send.
586 */
587 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
588 sctp_log_fr(0,
589 chk->sent_rcv_time.tv_sec,
590 chk->sent_rcv_time.tv_usec,
591 SCTP_FR_T3_STOPPED);
592 }
593 continue;
594 } else if ((chk->sent_rcv_time.tv_sec == min_wait.tv_sec) &&
595 (window_probe == 0)) {
596 /*
597 * we must look at the micro seconds to
598 * know.
599 */
600 if (chk->sent_rcv_time.tv_usec >= min_wait.tv_usec) {
601 /*
602 * ok it was sent after our boundary
603 * time.
604 */
605 continue;
606 }
607 }
608 if (stcb->asoc.peer_supports_prsctp && PR_SCTP_TTL_ENABLED(chk->flags)) {
609 /* Is it expired? */
610 if (timevalcmp(&now, &chk->rec.data.timetodrop, >)) {
611 /* Yes so drop it */
612 if (chk->data) {
613 (void)sctp_release_pr_sctp_chunk(stcb,
614 chk,
615 1,
616 SCTP_SO_NOT_LOCKED);
617 cnt_abandoned++;
618 }
619 continue;
620 }
621 }
622 if (stcb->asoc.peer_supports_prsctp && PR_SCTP_RTX_ENABLED(chk->flags)) {
623 /* Has it been retransmitted tv_sec times? */
624 if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) {
625 if (chk->data) {
626 (void)sctp_release_pr_sctp_chunk(stcb,
627 chk,
628 1,
629 SCTP_SO_NOT_LOCKED);
630 cnt_abandoned++;
631 }
632 continue;
633 }
634 }
635 if (chk->sent < SCTP_DATAGRAM_RESEND) {
636 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
637 num_mk++;
638 if (fir == 0) {
639 fir = 1;
640 tsnfirst = chk->rec.data.TSN_seq;
641 }
642 tsnlast = chk->rec.data.TSN_seq;
643 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
644 sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count,
645 0, SCTP_FR_T3_MARKED);
646 }
647 if (chk->rec.data.chunk_was_revoked) {
648 /* deflate the cwnd */
649 chk->whoTo->cwnd -= chk->book_size;
650 chk->rec.data.chunk_was_revoked = 0;
651 }
652 net->marked_retrans++;
653 stcb->asoc.marked_retrans++;
654 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
655 sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_RSND_TO,
656 chk->whoTo->flight_size,
657 chk->book_size,
658 (uintptr_t) chk->whoTo,
659 chk->rec.data.TSN_seq);
660 }
661 sctp_flight_size_decrease(chk);
662 sctp_total_flight_decrease(stcb, chk);
663 stcb->asoc.peers_rwnd += chk->send_size;
664 stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh);
665 }
666 chk->sent = SCTP_DATAGRAM_RESEND;
667 SCTP_STAT_INCR(sctps_markedretrans);
668
669 /* reset the TSN for striking and other FR stuff */
670 chk->rec.data.doing_fast_retransmit = 0;
671 /* Clear any time so NO RTT is being done */
672
673 if (chk->do_rtt) {
674 if (chk->whoTo->rto_needed == 0) {
675 chk->whoTo->rto_needed = 1;
676 }
677 }
678 chk->do_rtt = 0;
679 if (alt != net) {
680 sctp_free_remote_addr(chk->whoTo);
681 chk->no_fr_allowed = 1;
682 chk->whoTo = alt;
683 atomic_add_int(&alt->ref_count, 1);
684 } else {
685 chk->no_fr_allowed = 0;
686 if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
687 chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
688 } else {
689 chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
690 }
691 }
692 /*
693 * CMT: Do not allow FRs on retransmitted TSNs.
694 */
695 if (stcb->asoc.sctp_cmt_on_off > 0) {
696 chk->no_fr_allowed = 1;
697 }
698 #ifdef THIS_SHOULD_NOT_BE_DONE
699 } else if (chk->sent == SCTP_DATAGRAM_ACKED) {
700 /* remember highest acked one */
701 could_be_sent = chk;
702 #endif
703 }
704 if (chk->sent == SCTP_DATAGRAM_RESEND) {
705 cnt_mk++;
706 }
707 }
708 if ((orig_flight - net->flight_size) != (orig_tf - stcb->asoc.total_flight)) {
709 /* we did not subtract the same things? */
710 audit_tf = 1;
711 }
712 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
713 sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT);
714 }
715 #ifdef SCTP_DEBUG
716 if (num_mk) {
717 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
718 tsnlast);
719 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%ld\n",
720 num_mk, (u_long)stcb->asoc.peers_rwnd);
721 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
722 tsnlast);
723 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%d\n",
724 num_mk,
725 (int)stcb->asoc.peers_rwnd);
726 }
727 #endif
728 *num_marked = num_mk;
729 *num_abandoned = cnt_abandoned;
730 /*
731 * Now check for a ECN Echo that may be stranded And include the
732 * cnt_mk'd to have all resends in the control queue.
733 */
734 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
735 if (chk->sent == SCTP_DATAGRAM_RESEND) {
736 cnt_mk++;
737 }
738 if ((chk->whoTo == net) &&
739 (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
740 sctp_free_remote_addr(chk->whoTo);
741 chk->whoTo = alt;
742 if (chk->sent != SCTP_DATAGRAM_RESEND) {
743 chk->sent = SCTP_DATAGRAM_RESEND;
744 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
745 cnt_mk++;
746 }
747 atomic_add_int(&alt->ref_count, 1);
748 }
749 }
750 #ifdef THIS_SHOULD_NOT_BE_DONE
751 if ((stcb->asoc.sent_queue_retran_cnt == 0) && (could_be_sent)) {
752 /* fix it so we retransmit the highest acked anyway */
753 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
754 cnt_mk++;
755 could_be_sent->sent = SCTP_DATAGRAM_RESEND;
756 }
757 #endif
758 if (stcb->asoc.sent_queue_retran_cnt != cnt_mk) {
759 #ifdef INVARIANTS
760 SCTP_PRINTF("Local Audit says there are %d for retran asoc cnt:%d we marked:%d this time\n",
761 cnt_mk, stcb->asoc.sent_queue_retran_cnt, num_mk);
762 #endif
763 #ifndef SCTP_AUDITING_ENABLED
764 stcb->asoc.sent_queue_retran_cnt = cnt_mk;
765 #endif
766 }
767 if (audit_tf) {
768 SCTPDBG(SCTP_DEBUG_TIMER4,
769 "Audit total flight due to negative value net:%p\n",
770 net);
771 stcb->asoc.total_flight = 0;
772 stcb->asoc.total_flight_count = 0;
773 /* Clear all networks flight size */
774 TAILQ_FOREACH(lnets, &stcb->asoc.nets, sctp_next) {
775 lnets->flight_size = 0;
776 SCTPDBG(SCTP_DEBUG_TIMER4,
777 "Net:%p c-f cwnd:%d ssthresh:%d\n",
778 lnets, lnets->cwnd, lnets->ssthresh);
779 }
780 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
781 if (chk->sent < SCTP_DATAGRAM_RESEND) {
782 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
783 sctp_misc_ints(SCTP_FLIGHT_LOG_UP,
784 chk->whoTo->flight_size,
785 chk->book_size,
786 (uintptr_t) chk->whoTo,
787 chk->rec.data.TSN_seq);
788 }
789 sctp_flight_size_increase(chk);
790 sctp_total_flight_increase(stcb, chk);
791 }
792 }
793 }
794 /* We return 1 if we only have a window probe outstanding */
795 return (0);
796 }
797
798
799 int
800 sctp_t3rxt_timer(struct sctp_inpcb *inp,
801 struct sctp_tcb *stcb,
802 struct sctp_nets *net)
803 {
804 struct sctp_nets *alt;
805 int win_probe, num_mk, num_abandoned;
806
807 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
808 sctp_log_fr(0, 0, 0, SCTP_FR_T3_TIMEOUT);
809 }
810 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
811 struct sctp_nets *lnet;
812
813 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
814 if (net == lnet) {
815 sctp_log_cwnd(stcb, lnet, 1, SCTP_CWND_LOG_FROM_T3);
816 } else {
817 sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_LOG_FROM_T3);
818 }
819 }
820 }
821 /* Find an alternate and mark those for retransmission */
822 if ((stcb->asoc.peers_rwnd == 0) &&
823 (stcb->asoc.total_flight < net->mtu)) {
824 SCTP_STAT_INCR(sctps_timowindowprobe);
825 win_probe = 1;
826 } else {
827 win_probe = 0;
828 }
829
830 if (win_probe == 0) {
831 /* We don't do normal threshold management on window probes */
832 if (sctp_threshold_management(inp, stcb, net,
833 stcb->asoc.max_send_times)) {
834 /* Association was destroyed */
835 return (1);
836 } else {
837 if (net != stcb->asoc.primary_destination) {
838 /* send a immediate HB if our RTO is stale */
839 struct timeval now;
840 unsigned int ms_goneby;
841
842 (void)SCTP_GETTIME_TIMEVAL(&now);
843 if (net->last_sent_time.tv_sec) {
844 ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000;
845 } else {
846 ms_goneby = 0;
847 }
848 if ((net->dest_state & SCTP_ADDR_PF) == 0) {
849 if ((ms_goneby > net->RTO) || (net->RTO == 0)) {
850 /*
851 * no recent feed back in an
852 * RTO or more, request a
853 * RTT update
854 */
855 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
856 }
857 }
858 }
859 }
860 } else {
861 /*
862 * For a window probe we don't penalize the net's but only
863 * the association. This may fail it if SACKs are not coming
864 * back. If sack's are coming with rwnd locked at 0, we will
865 * continue to hold things waiting for rwnd to raise
866 */
867 if (sctp_threshold_management(inp, stcb, NULL,
868 stcb->asoc.max_send_times)) {
869 /* Association was destroyed */
870 return (1);
871 }
872 }
873 if (stcb->asoc.sctp_cmt_on_off > 0) {
874 if (net->pf_threshold < net->failure_threshold) {
875 alt = sctp_find_alternate_net(stcb, net, 2);
876 } else {
877 /*
878 * CMT: Using RTX_SSTHRESH policy for CMT. If CMT is
879 * being used, then pick dest with largest ssthresh
880 * for any retransmission.
881 */
882 alt = sctp_find_alternate_net(stcb, net, 1);
883 /*
884 * CUCv2: If a different dest is picked for the
885 * retransmission, then new (rtx-)pseudo_cumack
886 * needs to be tracked for orig dest. Let CUCv2
887 * track new (rtx-) pseudo-cumack always.
888 */
889 net->find_pseudo_cumack = 1;
890 net->find_rtx_pseudo_cumack = 1;
891 }
892 } else {
893 alt = sctp_find_alternate_net(stcb, net, 0);
894 }
895
896 num_mk = 0;
897 num_abandoned = 0;
898 (void)sctp_mark_all_for_resend(stcb, net, alt, win_probe,
899 &num_mk, &num_abandoned);
900 /* FR Loss recovery just ended with the T3. */
901 stcb->asoc.fast_retran_loss_recovery = 0;
902
903 /* CMT FR loss recovery ended with the T3 */
904 net->fast_retran_loss_recovery = 0;
905 if ((stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) &&
906 (net->flight_size == 0)) {
907 (*stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) (stcb, net);
908 }
909 /*
910 * setup the sat loss recovery that prevents satellite cwnd advance.
911 */
912 stcb->asoc.sat_t3_loss_recovery = 1;
913 stcb->asoc.sat_t3_recovery_tsn = stcb->asoc.sending_seq;
914
915 /* Backoff the timer and cwnd */
916 sctp_backoff_on_timeout(stcb, net, win_probe, num_mk, num_abandoned);
917 if ((!(net->dest_state & SCTP_ADDR_REACHABLE)) ||
918 (net->dest_state & SCTP_ADDR_PF)) {
919 /* Move all pending over too */
920 sctp_move_chunks_from_net(stcb, net);
921
922 /*
923 * Get the address that failed, to force a new src address
924 * selecton and a route allocation.
925 */
926 if (net->ro._s_addr) {
927 sctp_free_ifa(net->ro._s_addr);
928 net->ro._s_addr = NULL;
929 }
930 net->src_addr_selected = 0;
931
932 /* Force a route allocation too */
933 if (net->ro.ro_rt) {
934 RTFREE(net->ro.ro_rt);
935 net->ro.ro_rt = NULL;
936 }
937 /* Was it our primary? */
938 if ((stcb->asoc.primary_destination == net) && (alt != net)) {
939 /*
940 * Yes, note it as such and find an alternate note:
941 * this means HB code must use this to resent the
942 * primary if it goes active AND if someone does a
943 * change-primary then this flag must be cleared
944 * from any net structures.
945 */
946 if (stcb->asoc.alternate) {
947 sctp_free_remote_addr(stcb->asoc.alternate);
948 }
949 stcb->asoc.alternate = alt;
950 atomic_add_int(&stcb->asoc.alternate->ref_count, 1);
951 }
952 }
953 /*
954 * Special case for cookie-echo'ed case, we don't do output but must
955 * await the COOKIE-ACK before retransmission
956 */
957 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
958 /*
959 * Here we just reset the timer and start again since we
960 * have not established the asoc
961 */
962 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
963 return (0);
964 }
965 if (stcb->asoc.peer_supports_prsctp) {
966 struct sctp_tmit_chunk *lchk;
967
968 lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
969 /* C3. See if we need to send a Fwd-TSN */
970 if (SCTP_TSN_GT(stcb->asoc.advanced_peer_ack_point, stcb->asoc.last_acked_seq)) {
971 send_forward_tsn(stcb, &stcb->asoc);
972 if (lchk) {
973 /* Assure a timer is up */
974 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
975 }
976 }
977 }
978 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
979 sctp_log_cwnd(stcb, net, net->cwnd, SCTP_CWND_LOG_FROM_RTX);
980 }
981 return (0);
982 }
983
984 int
985 sctp_t1init_timer(struct sctp_inpcb *inp,
986 struct sctp_tcb *stcb,
987 struct sctp_nets *net)
988 {
989 /* bump the thresholds */
990 if (stcb->asoc.delayed_connection) {
991 /*
992 * special hook for delayed connection. The library did NOT
993 * complete the rest of its sends.
994 */
995 stcb->asoc.delayed_connection = 0;
996 sctp_send_initiate(inp, stcb, SCTP_SO_NOT_LOCKED);
997 return (0);
998 }
999 if (SCTP_GET_STATE((&stcb->asoc)) != SCTP_STATE_COOKIE_WAIT) {
1000 return (0);
1001 }
1002 if (sctp_threshold_management(inp, stcb, net,
1003 stcb->asoc.max_init_times)) {
1004 /* Association was destroyed */
1005 return (1);
1006 }
1007 stcb->asoc.dropped_special_cnt = 0;
1008 sctp_backoff_on_timeout(stcb, stcb->asoc.primary_destination, 1, 0, 0);
1009 if (stcb->asoc.initial_init_rto_max < net->RTO) {
1010 net->RTO = stcb->asoc.initial_init_rto_max;
1011 }
1012 if (stcb->asoc.numnets > 1) {
1013 /* If we have more than one addr use it */
1014 struct sctp_nets *alt;
1015
1016 alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination, 0);
1017 if (alt != stcb->asoc.primary_destination) {
1018 sctp_move_chunks_from_net(stcb, stcb->asoc.primary_destination);
1019 stcb->asoc.primary_destination = alt;
1020 }
1021 }
1022 /* Send out a new init */
1023 sctp_send_initiate(inp, stcb, SCTP_SO_NOT_LOCKED);
1024 return (0);
1025 }
1026
1027 /*
1028 * For cookie and asconf we actually need to find and mark for resend, then
1029 * increment the resend counter (after all the threshold management stuff of
1030 * course).
1031 */
1032 int
1033 sctp_cookie_timer(struct sctp_inpcb *inp,
1034 struct sctp_tcb *stcb,
1035 struct sctp_nets *net SCTP_UNUSED)
1036 {
1037 struct sctp_nets *alt;
1038 struct sctp_tmit_chunk *cookie;
1039
1040 /* first before all else we must find the cookie */
1041 TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, sctp_next) {
1042 if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
1043 break;
1044 }
1045 }
1046 if (cookie == NULL) {
1047 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
1048 /* FOOBAR! */
1049 struct mbuf *oper;
1050
1051 oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
1052 0, M_DONTWAIT, 1, MT_DATA);
1053 if (oper) {
1054 struct sctp_paramhdr *ph;
1055 uint32_t *ippp;
1056
1057 SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
1058 sizeof(uint32_t);
1059 ph = mtod(oper, struct sctp_paramhdr *);
1060 ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
1061 ph->param_length = htons(SCTP_BUF_LEN(oper));
1062 ippp = (uint32_t *) (ph + 1);
1063 *ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
1064 }
1065 inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_4;
1066 sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
1067 } else {
1068 #ifdef INVARIANTS
1069 panic("Cookie timer expires in wrong state?");
1070 #else
1071 SCTP_PRINTF("Strange in state %d not cookie-echoed yet c-e timer expires?\n", SCTP_GET_STATE(&stcb->asoc));
1072 return (0);
1073 #endif
1074 }
1075 return (0);
1076 }
1077 /* Ok we found the cookie, threshold management next */
1078 if (sctp_threshold_management(inp, stcb, cookie->whoTo,
1079 stcb->asoc.max_init_times)) {
1080 /* Assoc is over */
1081 return (1);
1082 }
1083 /*
1084 * cleared theshold management now lets backoff the address & select
1085 * an alternate
1086 */
1087 stcb->asoc.dropped_special_cnt = 0;
1088 sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0, 0);
1089 alt = sctp_find_alternate_net(stcb, cookie->whoTo, 0);
1090 if (alt != cookie->whoTo) {
1091 sctp_free_remote_addr(cookie->whoTo);
1092 cookie->whoTo = alt;
1093 atomic_add_int(&alt->ref_count, 1);
1094 }
1095 /* Now mark the retran info */
1096 if (cookie->sent != SCTP_DATAGRAM_RESEND) {
1097 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1098 }
1099 cookie->sent = SCTP_DATAGRAM_RESEND;
1100 /*
1101 * Now call the output routine to kick out the cookie again, Note we
1102 * don't mark any chunks for retran so that FR will need to kick in
1103 * to move these (or a send timer).
1104 */
1105 return (0);
1106 }
1107
1108 int
1109 sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1110 struct sctp_nets *net)
1111 {
1112 struct sctp_nets *alt;
1113 struct sctp_tmit_chunk *strrst = NULL, *chk = NULL;
1114
1115 if (stcb->asoc.stream_reset_outstanding == 0) {
1116 return (0);
1117 }
1118 /* find the existing STRRESET, we use the seq number we sent out on */
1119 (void)sctp_find_stream_reset(stcb, stcb->asoc.str_reset_seq_out, &strrst);
1120 if (strrst == NULL) {
1121 return (0);
1122 }
1123 /* do threshold management */
1124 if (sctp_threshold_management(inp, stcb, strrst->whoTo,
1125 stcb->asoc.max_send_times)) {
1126 /* Assoc is over */
1127 return (1);
1128 }
1129 /*
1130 * cleared theshold management now lets backoff the address & select
1131 * an alternate
1132 */
1133 sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0, 0);
1134 alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0);
1135 sctp_free_remote_addr(strrst->whoTo);
1136 strrst->whoTo = alt;
1137 atomic_add_int(&alt->ref_count, 1);
1138
1139 /* See if a ECN Echo is also stranded */
1140 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1141 if ((chk->whoTo == net) &&
1142 (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
1143 sctp_free_remote_addr(chk->whoTo);
1144 if (chk->sent != SCTP_DATAGRAM_RESEND) {
1145 chk->sent = SCTP_DATAGRAM_RESEND;
1146 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1147 }
1148 chk->whoTo = alt;
1149 atomic_add_int(&alt->ref_count, 1);
1150 }
1151 }
1152 if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
1153 /*
1154 * If the address went un-reachable, we need to move to
1155 * alternates for ALL chk's in queue
1156 */
1157 sctp_move_chunks_from_net(stcb, net);
1158 }
1159 /* mark the retran info */
1160 if (strrst->sent != SCTP_DATAGRAM_RESEND)
1161 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1162 strrst->sent = SCTP_DATAGRAM_RESEND;
1163
1164 /* restart the timer */
1165 sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo);
1166 return (0);
1167 }
1168
1169 int
1170 sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1171 struct sctp_nets *net)
1172 {
1173 struct sctp_nets *alt;
1174 struct sctp_tmit_chunk *asconf, *chk;
1175
1176 /* is this a first send, or a retransmission? */
1177 if (TAILQ_EMPTY(&stcb->asoc.asconf_send_queue)) {
1178 /* compose a new ASCONF chunk and send it */
1179 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
1180 } else {
1181 /*
1182 * Retransmission of the existing ASCONF is needed
1183 */
1184
1185 /* find the existing ASCONF */
1186 asconf = TAILQ_FIRST(&stcb->asoc.asconf_send_queue);
1187 if (asconf == NULL) {
1188 return (0);
1189 }
1190 /* do threshold management */
1191 if (sctp_threshold_management(inp, stcb, asconf->whoTo,
1192 stcb->asoc.max_send_times)) {
1193 /* Assoc is over */
1194 return (1);
1195 }
1196 if (asconf->snd_count > stcb->asoc.max_send_times) {
1197 /*
1198 * Something is rotten: our peer is not responding
1199 * to ASCONFs but apparently is to other chunks.
1200 * i.e. it is not properly handling the chunk type
1201 * upper bits. Mark this peer as ASCONF incapable
1202 * and cleanup.
1203 */
1204 SCTPDBG(SCTP_DEBUG_TIMER1, "asconf_timer: Peer has not responded to our repeated ASCONFs\n");
1205 sctp_asconf_cleanup(stcb, net);
1206 return (0);
1207 }
1208 /*
1209 * cleared threshold management, so now backoff the net and
1210 * select an alternate
1211 */
1212 sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0, 0);
1213 alt = sctp_find_alternate_net(stcb, asconf->whoTo, 0);
1214 if (asconf->whoTo != alt) {
1215 sctp_free_remote_addr(asconf->whoTo);
1216 asconf->whoTo = alt;
1217 atomic_add_int(&alt->ref_count, 1);
1218 }
1219 /* See if an ECN Echo is also stranded */
1220 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1221 if ((chk->whoTo == net) &&
1222 (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
1223 sctp_free_remote_addr(chk->whoTo);
1224 chk->whoTo = alt;
1225 if (chk->sent != SCTP_DATAGRAM_RESEND) {
1226 chk->sent = SCTP_DATAGRAM_RESEND;
1227 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1228 }
1229 atomic_add_int(&alt->ref_count, 1);
1230 }
1231 }
1232 TAILQ_FOREACH(chk, &stcb->asoc.asconf_send_queue, sctp_next) {
1233 if (chk->whoTo != alt) {
1234 sctp_free_remote_addr(chk->whoTo);
1235 chk->whoTo = alt;
1236 atomic_add_int(&alt->ref_count, 1);
1237 }
1238 if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT)
1239 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1240 chk->sent = SCTP_DATAGRAM_RESEND;
1241 }
1242 if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
1243 /*
1244 * If the address went un-reachable, we need to move
1245 * to the alternate for ALL chunks in queue
1246 */
1247 sctp_move_chunks_from_net(stcb, net);
1248 }
1249 /* mark the retran info */
1250 if (asconf->sent != SCTP_DATAGRAM_RESEND)
1251 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1252 asconf->sent = SCTP_DATAGRAM_RESEND;
1253
1254 /* send another ASCONF if any and we can do */
1255 sctp_send_asconf(stcb, alt, SCTP_ADDR_NOT_LOCKED);
1256 }
1257 return (0);
1258 }
1259
1260 /* Mobility adaptation */
1261 void
1262 sctp_delete_prim_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1263 struct sctp_nets *net SCTP_UNUSED)
1264 {
1265 if (stcb->asoc.deleted_primary == NULL) {
1266 SCTPDBG(SCTP_DEBUG_ASCONF1, "delete_prim_timer: deleted_primary is not stored...\n");
1267 sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
1268 return;
1269 }
1270 SCTPDBG(SCTP_DEBUG_ASCONF1, "delete_prim_timer: finished to keep deleted primary ");
1271 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
1272 sctp_free_remote_addr(stcb->asoc.deleted_primary);
1273 stcb->asoc.deleted_primary = NULL;
1274 sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
1275 return;
1276 }
1277
1278 /*
1279 * For the shutdown and shutdown-ack, we do not keep one around on the
1280 * control queue. This means we must generate a new one and call the general
1281 * chunk output routine, AFTER having done threshold management.
1282 * It is assumed that net is non-NULL.
1283 */
1284 int
1285 sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1286 struct sctp_nets *net)
1287 {
1288 struct sctp_nets *alt;
1289
1290 /* first threshold managment */
1291 if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1292 /* Assoc is over */
1293 return (1);
1294 }
1295 sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
1296 /* second select an alternative */
1297 alt = sctp_find_alternate_net(stcb, net, 0);
1298
1299 /* third generate a shutdown into the queue for out net */
1300 sctp_send_shutdown(stcb, alt);
1301
1302 /* fourth restart timer */
1303 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt);
1304 return (0);
1305 }
1306
1307 int
1308 sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1309 struct sctp_nets *net)
1310 {
1311 struct sctp_nets *alt;
1312
1313 /* first threshold managment */
1314 if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1315 /* Assoc is over */
1316 return (1);
1317 }
1318 sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
1319 /* second select an alternative */
1320 alt = sctp_find_alternate_net(stcb, net, 0);
1321
1322 /* third generate a shutdown into the queue for out net */
1323 sctp_send_shutdown_ack(stcb, alt);
1324
1325 /* fourth restart timer */
1326 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, alt);
1327 return (0);
1328 }
1329
1330 static void
1331 sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
1332 struct sctp_tcb *stcb)
1333 {
1334 struct sctp_stream_queue_pending *sp;
1335 unsigned int i, chks_in_queue = 0;
1336 int being_filled = 0;
1337
1338 /*
1339 * This function is ONLY called when the send/sent queues are empty.
1340 */
1341 if ((stcb == NULL) || (inp == NULL))
1342 return;
1343
1344 if (stcb->asoc.sent_queue_retran_cnt) {
1345 SCTP_PRINTF("Hmm, sent_queue_retran_cnt is non-zero %d\n",
1346 stcb->asoc.sent_queue_retran_cnt);
1347 stcb->asoc.sent_queue_retran_cnt = 0;
1348 }
1349 if (stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
1350 /* No stream scheduler information, initialize scheduler */
1351 stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 0);
1352 if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
1353 /* yep, we lost a stream or two */
1354 SCTP_PRINTF("Found additional streams NOT managed by scheduler, corrected\n");
1355 } else {
1356 /* no streams lost */
1357 stcb->asoc.total_output_queue_size = 0;
1358 }
1359 }
1360 /* Check to see if some data queued, if so report it */
1361 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
1362 if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
1363 TAILQ_FOREACH(sp, &stcb->asoc.strmout[i].outqueue, next) {
1364 if (sp->msg_is_complete)
1365 being_filled++;
1366 chks_in_queue++;
1367 }
1368 }
1369 }
1370 if (chks_in_queue != stcb->asoc.stream_queue_cnt) {
1371 SCTP_PRINTF("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
1372 stcb->asoc.stream_queue_cnt, chks_in_queue);
1373 }
1374 if (chks_in_queue) {
1375 /* call the output queue function */
1376 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1377 if ((TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1378 (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1379 /*
1380 * Probably should go in and make it go back through
1381 * and add fragments allowed
1382 */
1383 if (being_filled == 0) {
1384 SCTP_PRINTF("Still nothing moved %d chunks are stuck\n",
1385 chks_in_queue);
1386 }
1387 }
1388 } else {
1389 SCTP_PRINTF("Found no chunks on any queue tot:%lu\n",
1390 (u_long)stcb->asoc.total_output_queue_size);
1391 stcb->asoc.total_output_queue_size = 0;
1392 }
1393 }
1394
1395 int
1396 sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1397 struct sctp_nets *net)
1398 {
1399 uint8_t net_was_pf;
1400
1401 if (net->dest_state & SCTP_ADDR_PF) {
1402 net_was_pf = 1;
1403 } else {
1404 net_was_pf = 0;
1405 }
1406 if (net->hb_responded == 0) {
1407 if (net->ro._s_addr) {
1408 /*
1409 * Invalidate the src address if we did not get a
1410 * response last time.
1411 */
1412 sctp_free_ifa(net->ro._s_addr);
1413 net->ro._s_addr = NULL;
1414 net->src_addr_selected = 0;
1415 }
1416 sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
1417 if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1418 /* Assoc is over */
1419 return (1);
1420 }
1421 }
1422 /* Zero PBA, if it needs it */
1423 if (net->partial_bytes_acked) {
1424 net->partial_bytes_acked = 0;
1425 }
1426 if ((stcb->asoc.total_output_queue_size > 0) &&
1427 (TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1428 (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1429 sctp_audit_stream_queues_for_size(inp, stcb);
1430 }
1431 if (!(net->dest_state & SCTP_ADDR_NOHB) &&
1432 !((net_was_pf == 0) && (net->dest_state & SCTP_ADDR_PF))) {
1433 /*
1434 * when move to PF during threshold mangement, a HB has been
1435 * queued in that routine
1436 */
1437 uint32_t ms_gone_by;
1438
1439 if ((net->last_sent_time.tv_sec > 0) ||
1440 (net->last_sent_time.tv_usec > 0)) {
1441 struct timeval diff;
1442
1443 SCTP_GETTIME_TIMEVAL(&diff);
1444 timevalsub(&diff, &net->last_sent_time);
1445 ms_gone_by = (uint32_t) (diff.tv_sec * 1000) +
1446 (uint32_t) (diff.tv_usec / 1000);
1447 } else {
1448 ms_gone_by = 0xffffffff;
1449 }
1450 if ((ms_gone_by >= net->heart_beat_delay) ||
1451 (net->dest_state & SCTP_ADDR_PF)) {
1452 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
1453 }
1454 }
1455 return (0);
1456 }
1457
1458 void
1459 sctp_pathmtu_timer(struct sctp_inpcb *inp,
1460 struct sctp_tcb *stcb,
1461 struct sctp_nets *net)
1462 {
1463 uint32_t next_mtu, mtu;
1464
1465 next_mtu = sctp_get_next_mtu(net->mtu);
1466
1467 if ((next_mtu > net->mtu) && (net->port == 0)) {
1468 if ((net->src_addr_selected == 0) ||
1469 (net->ro._s_addr == NULL) ||
1470 (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
1471 if ((net->ro._s_addr != NULL) && (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
1472 sctp_free_ifa(net->ro._s_addr);
1473 net->ro._s_addr = NULL;
1474 net->src_addr_selected = 0;
1475 } else if (net->ro._s_addr == NULL) {
1476 #if defined(INET6) && defined(SCTP_EMBEDDED_V6_SCOPE)
1477 if (net->ro._l_addr.sa.sa_family == AF_INET6) {
1478 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1479
1480 /* KAME hack: embed scopeid */
1481 (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
1482 }
1483 #endif
1484
1485 net->ro._s_addr = sctp_source_address_selection(inp,
1486 stcb,
1487 (sctp_route_t *) & net->ro,
1488 net, 0, stcb->asoc.vrf_id);
1489 #if defined(INET6) && defined(SCTP_EMBEDDED_V6_SCOPE)
1490 if (net->ro._l_addr.sa.sa_family == AF_INET6) {
1491 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1492
1493 (void)sa6_recoverscope(sin6);
1494 }
1495 #endif /* INET6 */
1496 }
1497 if (net->ro._s_addr)
1498 net->src_addr_selected = 1;
1499 }
1500 if (net->ro._s_addr) {
1501 mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
1502 if (net->port) {
1503 mtu -= sizeof(struct udphdr);
1504 }
1505 if (mtu > next_mtu) {
1506 net->mtu = next_mtu;
1507 }
1508 }
1509 }
1510 /* restart the timer */
1511 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
1512 }
1513
1514 void
1515 sctp_autoclose_timer(struct sctp_inpcb *inp,
1516 struct sctp_tcb *stcb,
1517 struct sctp_nets *net)
1518 {
1519 struct timeval tn, *tim_touse;
1520 struct sctp_association *asoc;
1521 int ticks_gone_by;
1522
1523 (void)SCTP_GETTIME_TIMEVAL(&tn);
1524 if (stcb->asoc.sctp_autoclose_ticks &&
1525 sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
1526 /* Auto close is on */
1527 asoc = &stcb->asoc;
1528 /* pick the time to use */
1529 if (asoc->time_last_rcvd.tv_sec >
1530 asoc->time_last_sent.tv_sec) {
1531 tim_touse = &asoc->time_last_rcvd;
1532 } else {
1533 tim_touse = &asoc->time_last_sent;
1534 }
1535 /* Now has long enough transpired to autoclose? */
1536 ticks_gone_by = SEC_TO_TICKS(tn.tv_sec - tim_touse->tv_sec);
1537 if ((ticks_gone_by > 0) &&
1538 (ticks_gone_by >= (int)asoc->sctp_autoclose_ticks)) {
1539 /*
1540 * autoclose time has hit, call the output routine,
1541 * which should do nothing just to be SURE we don't
1542 * have hanging data. We can then safely check the
1543 * queues and know that we are clear to send
1544 * shutdown
1545 */
1546 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR, SCTP_SO_NOT_LOCKED);
1547 /* Are we clean? */
1548 if (TAILQ_EMPTY(&asoc->send_queue) &&
1549 TAILQ_EMPTY(&asoc->sent_queue)) {
1550 /*
1551 * there is nothing queued to send, so I'm
1552 * done...
1553 */
1554 if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
1555 /* only send SHUTDOWN 1st time thru */
1556 struct sctp_nets *netp;
1557
1558 if (stcb->asoc.alternate) {
1559 netp = stcb->asoc.alternate;
1560 } else {
1561 netp = stcb->asoc.primary_destination;
1562 }
1563 sctp_send_shutdown(stcb, netp);
1564 if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
1565 (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
1566 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
1567 }
1568 SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
1569 SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
1570 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
1571 stcb->sctp_ep, stcb,
1572 netp);
1573 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1574 stcb->sctp_ep, stcb,
1575 netp);
1576 }
1577 }
1578 } else {
1579 /*
1580 * No auto close at this time, reset t-o to check
1581 * later
1582 */
1583 int tmp;
1584
1585 /* fool the timer startup to use the time left */
1586 tmp = asoc->sctp_autoclose_ticks;
1587 asoc->sctp_autoclose_ticks -= ticks_gone_by;
1588 sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
1589 net);
1590 /* restore the real tick value */
1591 asoc->sctp_autoclose_ticks = tmp;
1592 }
1593 }
1594 }
Cache object: ce024e2a0da28be7bb189f114964518f
|