sctp_timer.c (216669) | sctp_timer.c (216822) |
---|---|
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. --- 17 unchanged lines hidden (view full) --- 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> | 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. --- 17 unchanged lines hidden (view full) --- 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 216669 2010-12-22 17:59:38Z tuexen $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 216822 2010-12-30 16:56:20Z 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> --- 9 unchanged lines hidden (view full) --- 52#include <netinet/udp.h> 53 54 55void 56sctp_early_fr_timer(struct sctp_inpcb *inp, 57 struct sctp_tcb *stcb, 58 struct sctp_nets *net) 59{ | 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> --- 9 unchanged lines hidden (view full) --- 52#include <netinet/udp.h> 53 54 55void 56sctp_early_fr_timer(struct sctp_inpcb *inp, 57 struct sctp_tcb *stcb, 58 struct sctp_nets *net) 59{ |
60 struct sctp_tmit_chunk *chk, *tp2; | 60 struct sctp_tmit_chunk *chk, *pchk; |
61 struct timeval now, min_wait, tv; 62 unsigned int cur_rtt, cnt = 0, cnt_resend = 0; 63 64 /* an early FR is occuring. */ 65 (void)SCTP_GETTIME_TIMEVAL(&now); 66 /* get cur rto in micro-seconds */ 67 if (net->lastsa == 0) { 68 /* Hmm no rtt estimate yet? */ --- 14 unchanged lines hidden (view full) --- 83 /* 84 * if we hit here, we don't have enough seconds on the clock 85 * to account for the RTO. We just let the lower seconds be 86 * the bounds and don't worry about it. This may mean we 87 * will mark a lot more than we should. 88 */ 89 min_wait.tv_sec = min_wait.tv_usec = 0; 90 } | 61 struct timeval now, min_wait, tv; 62 unsigned int cur_rtt, cnt = 0, cnt_resend = 0; 63 64 /* an early FR is occuring. */ 65 (void)SCTP_GETTIME_TIMEVAL(&now); 66 /* get cur rto in micro-seconds */ 67 if (net->lastsa == 0) { 68 /* Hmm no rtt estimate yet? */ --- 14 unchanged lines hidden (view full) --- 83 /* 84 * if we hit here, we don't have enough seconds on the clock 85 * to account for the RTO. We just let the lower seconds be 86 * the bounds and don't worry about it. This may mean we 87 * will mark a lot more than we should. 88 */ 89 min_wait.tv_sec = min_wait.tv_usec = 0; 90 } |
91 chk = TAILQ_LAST(&stcb->asoc.sent_queue, sctpchunk_listhead); 92 for (; chk != NULL; chk = tp2) { 93 tp2 = TAILQ_PREV(chk, sctpchunk_listhead, sctp_next); | 91 TAILQ_FOREACH_REVERSE_SAFE(chk, &stcb->asoc.sent_queue, sctpchunk_listhead, sctp_next, pchk) { |
94 if (chk->whoTo != net) { 95 continue; 96 } 97 if (chk->sent == SCTP_DATAGRAM_RESEND) 98 cnt_resend++; 99 else if ((chk->sent > SCTP_DATAGRAM_UNSENT) && 100 (chk->sent < SCTP_DATAGRAM_RESEND)) { 101 /* pending, may need retran */ --- 467 unchanged lines hidden (view full) --- 569 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout(stcb, net); 570 } 571} 572 573#ifndef INVARIANTS 574static void 575sctp_recover_sent_list(struct sctp_tcb *stcb) 576{ | 92 if (chk->whoTo != net) { 93 continue; 94 } 95 if (chk->sent == SCTP_DATAGRAM_RESEND) 96 cnt_resend++; 97 else if ((chk->sent > SCTP_DATAGRAM_UNSENT) && 98 (chk->sent < SCTP_DATAGRAM_RESEND)) { 99 /* pending, may need retran */ --- 467 unchanged lines hidden (view full) --- 567 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout(stcb, net); 568 } 569} 570 571#ifndef INVARIANTS 572static void 573sctp_recover_sent_list(struct sctp_tcb *stcb) 574{ |
577 struct sctp_tmit_chunk *chk, *tp2; | 575 struct sctp_tmit_chunk *chk, *nchk; |
578 struct sctp_association *asoc; 579 580 asoc = &stcb->asoc; | 576 struct sctp_association *asoc; 577 578 asoc = &stcb->asoc; |
581 chk = TAILQ_FIRST(&stcb->asoc.sent_queue); 582 for (; chk != NULL; chk = tp2) { 583 tp2 = TAILQ_NEXT(chk, sctp_next); 584 if ((compare_with_wrap(stcb->asoc.last_acked_seq, | 579 TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { 580 if ((compare_with_wrap(asoc->last_acked_seq, |
585 chk->rec.data.TSN_seq, 586 MAX_TSN)) || | 581 chk->rec.data.TSN_seq, 582 MAX_TSN)) || |
587 (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) { | 583 (asoc->last_acked_seq == chk->rec.data.TSN_seq)) { |
588 589 SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n", | 584 585 SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n", |
590 chk, chk->rec.data.TSN_seq, stcb->asoc.last_acked_seq); | 586 chk, chk->rec.data.TSN_seq, asoc->last_acked_seq); |
591 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); 592 if (chk->pr_sctp_on) { 593 if (asoc->pr_sctp_cnt != 0) 594 asoc->pr_sctp_cnt--; 595 } 596 if (chk->data) { 597 /* sa_ignore NO_NULL_CHK */ 598 sctp_free_bufspace(stcb, asoc, chk, 1); 599 sctp_m_freem(chk->data); | 587 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); 588 if (chk->pr_sctp_on) { 589 if (asoc->pr_sctp_cnt != 0) 590 asoc->pr_sctp_cnt--; 591 } 592 if (chk->data) { 593 /* sa_ignore NO_NULL_CHK */ 594 sctp_free_bufspace(stcb, asoc, chk, 1); 595 sctp_m_freem(chk->data); |
596 chk->data = NULL; |
|
600 if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) { 601 asoc->sent_queue_cnt_removeable--; 602 } 603 } | 597 if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) { 598 asoc->sent_queue_cnt_removeable--; 599 } 600 } |
604 chk->data = NULL; | |
605 asoc->sent_queue_cnt--; 606 sctp_free_a_chunk(stcb, chk); 607 } 608 } 609 SCTP_PRINTF("after recover order is as follows\n"); | 601 asoc->sent_queue_cnt--; 602 sctp_free_a_chunk(stcb, chk); 603 } 604 } 605 SCTP_PRINTF("after recover order is as follows\n"); |
610 chk = TAILQ_FIRST(&stcb->asoc.sent_queue); 611 for (; chk != NULL; chk = tp2) { 612 tp2 = TAILQ_NEXT(chk, sctp_next); | 606 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { |
613 SCTP_PRINTF("chk:%p TSN:%x\n", chk, chk->rec.data.TSN_seq); 614 } 615} 616 617#endif 618 619static int 620sctp_mark_all_for_resend(struct sctp_tcb *stcb, --- 5 unchanged lines hidden (view full) --- 626{ 627 628 /* 629 * Mark all chunks (well not all) that were sent to *net for 630 * retransmission. Move them to alt for there destination as well... 631 * We only mark chunks that have been outstanding long enough to 632 * have received feed-back. 633 */ | 607 SCTP_PRINTF("chk:%p TSN:%x\n", chk, chk->rec.data.TSN_seq); 608 } 609} 610 611#endif 612 613static int 614sctp_mark_all_for_resend(struct sctp_tcb *stcb, --- 5 unchanged lines hidden (view full) --- 620{ 621 622 /* 623 * Mark all chunks (well not all) that were sent to *net for 624 * retransmission. Move them to alt for there destination as well... 625 * We only mark chunks that have been outstanding long enough to 626 * have received feed-back. 627 */ |
634 struct sctp_tmit_chunk *chk, *tp2; | 628 struct sctp_tmit_chunk *chk, *nchk; |
635 struct sctp_nets *lnets; 636 struct timeval now, min_wait, tv; 637 int cur_rtt; 638 int cnt_abandoned; 639 int audit_tf, num_mk, fir; 640 unsigned int cnt_mk; 641 uint32_t orig_flight, orig_tf; 642 uint32_t tsnlast, tsnfirst; --- 49 unchanged lines hidden (view full) --- 692 net->fast_retran_ip = 0; 693 /* Now on to each chunk */ 694 cnt_abandoned = 0; 695 num_mk = cnt_mk = 0; 696 tsnfirst = tsnlast = 0; 697#ifndef INVARIANTS 698start_again: 699#endif | 629 struct sctp_nets *lnets; 630 struct timeval now, min_wait, tv; 631 int cur_rtt; 632 int cnt_abandoned; 633 int audit_tf, num_mk, fir; 634 unsigned int cnt_mk; 635 uint32_t orig_flight, orig_tf; 636 uint32_t tsnlast, tsnfirst; --- 49 unchanged lines hidden (view full) --- 686 net->fast_retran_ip = 0; 687 /* Now on to each chunk */ 688 cnt_abandoned = 0; 689 num_mk = cnt_mk = 0; 690 tsnfirst = tsnlast = 0; 691#ifndef INVARIANTS 692start_again: 693#endif |
700 chk = TAILQ_FIRST(&stcb->asoc.sent_queue); 701 for (; chk != NULL; chk = tp2) { 702 tp2 = TAILQ_NEXT(chk, sctp_next); | 694 TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) { |
703 if ((compare_with_wrap(stcb->asoc.last_acked_seq, 704 chk->rec.data.TSN_seq, 705 MAX_TSN)) || 706 (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) { 707 /* Strange case our list got out of order? */ 708 SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x", 709 (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq); 710 recovery_cnt++; --- 653 unchanged lines hidden (view full) --- 1364 return (0); 1365} 1366 1367int 1368sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1369 struct sctp_nets *net) 1370{ 1371 struct sctp_nets *alt; | 695 if ((compare_with_wrap(stcb->asoc.last_acked_seq, 696 chk->rec.data.TSN_seq, 697 MAX_TSN)) || 698 (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) { 699 /* Strange case our list got out of order? */ 700 SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x", 701 (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq); 702 recovery_cnt++; --- 653 unchanged lines hidden (view full) --- 1356 return (0); 1357} 1358 1359int 1360sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1361 struct sctp_nets *net) 1362{ 1363 struct sctp_nets *alt; |
1372 struct sctp_tmit_chunk *asconf, *chk, *nchk; | 1364 struct sctp_tmit_chunk *asconf, *chk; |
1373 1374 /* is this a first send, or a retransmission? */ 1375 if (TAILQ_EMPTY(&stcb->asoc.asconf_send_queue)) { 1376 /* compose a new ASCONF chunk and send it */ 1377 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED); 1378 } else { 1379 /* 1380 * Retransmission of the existing ASCONF is needed --- 41 unchanged lines hidden (view full) --- 1422 chk->whoTo = alt; 1423 if (chk->sent != SCTP_DATAGRAM_RESEND) { 1424 chk->sent = SCTP_DATAGRAM_RESEND; 1425 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1426 } 1427 atomic_add_int(&alt->ref_count, 1); 1428 } 1429 } | 1365 1366 /* is this a first send, or a retransmission? */ 1367 if (TAILQ_EMPTY(&stcb->asoc.asconf_send_queue)) { 1368 /* compose a new ASCONF chunk and send it */ 1369 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED); 1370 } else { 1371 /* 1372 * Retransmission of the existing ASCONF is needed --- 41 unchanged lines hidden (view full) --- 1414 chk->whoTo = alt; 1415 if (chk->sent != SCTP_DATAGRAM_RESEND) { 1416 chk->sent = SCTP_DATAGRAM_RESEND; 1417 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1418 } 1419 atomic_add_int(&alt->ref_count, 1); 1420 } 1421 } |
1430 for (chk = asconf; chk; chk = nchk) { 1431 nchk = TAILQ_NEXT(chk, sctp_next); | 1422 TAILQ_FOREACH(chk, &stcb->asoc.asconf_send_queue, sctp_next) { |
1432 if (chk->whoTo != alt) { 1433 sctp_free_remote_addr(chk->whoTo); 1434 chk->whoTo = alt; 1435 atomic_add_int(&alt->ref_count, 1); 1436 } 1437 if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT) 1438 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1439 chk->sent = SCTP_DATAGRAM_RESEND; --- 363 unchanged lines hidden --- | 1423 if (chk->whoTo != alt) { 1424 sctp_free_remote_addr(chk->whoTo); 1425 chk->whoTo = alt; 1426 atomic_add_int(&alt->ref_count, 1); 1427 } 1428 if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT) 1429 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 1430 chk->sent = SCTP_DATAGRAM_RESEND; --- 363 unchanged lines hidden --- |