sctp_indata.c (168124) | sctp_indata.c (168299) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, 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_indata.c,v 1.36 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, 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_indata.c,v 1.36 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 168124 2007-03-31 11:47:30Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 168299 2007-04-03 11:15:32Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_var.h> 38#include <netinet/sctp_sysctl.h> 39#include <netinet/sctp_pcb.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp_output.h> --- 4023 unchanged lines hidden (view full) --- 4066 } 4067 if (net->RTO > stcb->asoc.maxrto) { 4068 net->RTO = stcb->asoc.maxrto; 4069 } 4070 } 4071 } 4072} 4073 | 35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_var.h> 38#include <netinet/sctp_sysctl.h> 39#include <netinet/sctp_pcb.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp_output.h> --- 4023 unchanged lines hidden (view full) --- 4066 } 4067 if (net->RTO > stcb->asoc.maxrto) { 4068 net->RTO = stcb->asoc.maxrto; 4069 } 4070 } 4071 } 4072} 4073 |
4074static int sctp_anal_print = 0; |
|
4074 | 4075 |
4076static void 4077sctp_print_fs_audit(struct sctp_association *asoc) 4078{ 4079 int cnt, i; 4080 struct sctp_tmit_chunk *chk; 4081 int inflight = 0, resend = 0, inbetween = 0, acked = 0, above = 0; 4082 4083 printf("sdqc:%d stqc:%d retran:%d reasm:%d cnt:%d tot_flight:%d tfc:%d\n", 4084 (int)asoc->send_queue_cnt, 4085 (int)asoc->sent_queue_cnt, 4086 (int)asoc->sent_queue_retran_cnt, 4087 (int)asoc->size_on_reasm_queue, 4088 (int)asoc->cnt_on_reasm_queue, 4089 (int)asoc->total_flight, 4090 (int)asoc->total_flight_count); 4091 printf("my_rwnd:%d peers_rwnd:%d asoc calc cumack:%x\n", 4092 (int)asoc->my_rwnd, (int)asoc->peers_rwnd, asoc->last_acked_seq); 4093 for (i = 0; i < asoc->streamoutcnt; i++) { 4094 struct sctp_stream_queue_pending *sp; 4095 4096 cnt = 0; 4097 TAILQ_FOREACH(sp, &asoc->strmout[i].outqueue, next) 4098 cnt++; 4099 if (cnt) { 4100 printf("Stream %d has %d msgs yet to be sent in strm queue\n", i, cnt); 4101 } 4102 } 4103 cnt = 0; 4104 TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) { 4105 cnt++; 4106 } 4107 printf("The control_send_queue has %d pending\n", cnt); 4108 cnt = 0; 4109 TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) { 4110 cnt++; 4111 } 4112 printf("The send_queue (waiting to get in flight) has %d chunks pending\n", cnt); 4113 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { 4114 if (chk->sent < SCTP_DATAGRAM_RESEND) { 4115 inflight++; 4116 } else if (chk->sent == SCTP_DATAGRAM_RESEND) { 4117 resend++; 4118 } else if (chk->sent < SCTP_DATAGRAM_ACKED) { 4119 inbetween++; 4120 } else if (chk->sent > SCTP_DATAGRAM_ACKED) { 4121 above++; 4122 } else { 4123 acked++; 4124 printf("chk->sent:%x chk->tsn:%x\n", 4125 chk->sent, chk->rec.data.TSN_seq); 4126 } 4127 } 4128 printf("The sent_queue stats inflight:%d resend:%d acked:%d above:%d inbetween:%d\n", 4129 inflight, resend, acked, above, inbetween); 4130} 4131 |
|
4075void 4076sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, 4077 uint32_t rwnd, int nonce_sum_flag, int *abort_now) 4078{ 4079 struct sctp_nets *net; 4080 struct sctp_association *asoc; 4081 struct sctp_tmit_chunk *tp1, *tp2; 4082 uint32_t old_rwnd; 4083 int win_probe_recovery = 0; | 4132void 4133sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, 4134 uint32_t rwnd, int nonce_sum_flag, int *abort_now) 4135{ 4136 struct sctp_nets *net; 4137 struct sctp_association *asoc; 4138 struct sctp_tmit_chunk *tp1, *tp2; 4139 uint32_t old_rwnd; 4140 int win_probe_recovery = 0; |
4084 int j; | 4141 int j, done_once;; |
4085 4086 SCTP_TCB_LOCK_ASSERT(stcb); 4087 asoc = &stcb->asoc; 4088 if (compare_with_wrap(asoc->last_acked_seq, cumack, MAX_TSN)) { 4089 /* old ack */ 4090 return; 4091 } 4092 /* First setup for CC stuff */ --- 253 unchanged lines hidden (view full) --- 4346 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { 4347 /* SWS sender side engages */ 4348 asoc->peers_rwnd = 0; 4349 } 4350 if (asoc->peers_rwnd > old_rwnd) { 4351 win_probe_recovery = 1; 4352 } 4353 /* Now assure a timer where data is queued at */ | 4142 4143 SCTP_TCB_LOCK_ASSERT(stcb); 4144 asoc = &stcb->asoc; 4145 if (compare_with_wrap(asoc->last_acked_seq, cumack, MAX_TSN)) { 4146 /* old ack */ 4147 return; 4148 } 4149 /* First setup for CC stuff */ --- 253 unchanged lines hidden (view full) --- 4403 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { 4404 /* SWS sender side engages */ 4405 asoc->peers_rwnd = 0; 4406 } 4407 if (asoc->peers_rwnd > old_rwnd) { 4408 win_probe_recovery = 1; 4409 } 4410 /* Now assure a timer where data is queued at */ |
4411 done_once = 0; |
|
4354again: 4355 j = 0; 4356 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 4357 if (win_probe_recovery && (net->window_probe)) { 4358 net->window_probe = 0; 4359 /* 4360 * Find first chunk that was used with window probe 4361 * and clear the sent --- 35 unchanged lines hidden (view full) --- 4397 if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) { 4398 SCTP_STAT_INCR(sctps_earlyfrstpidsck4); 4399 sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net, 4400 SCTP_FROM_SCTP_INDATA + SCTP_LOC_23); 4401 } 4402 } 4403 } 4404 } | 4412again: 4413 j = 0; 4414 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 4415 if (win_probe_recovery && (net->window_probe)) { 4416 net->window_probe = 0; 4417 /* 4418 * Find first chunk that was used with window probe 4419 * and clear the sent --- 35 unchanged lines hidden (view full) --- 4455 if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) { 4456 SCTP_STAT_INCR(sctps_earlyfrstpidsck4); 4457 sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net, 4458 SCTP_FROM_SCTP_INDATA + SCTP_LOC_23); 4459 } 4460 } 4461 } 4462 } |
4405 if ((j == 0) && (!TAILQ_EMPTY(&asoc->sent_queue)) && (asoc->sent_queue_retran_cnt == 0)) { | 4463 if ((j == 0) && 4464 (!TAILQ_EMPTY(&asoc->sent_queue)) && 4465 (asoc->sent_queue_retran_cnt == 0) && 4466 (done_once == 0)) { |
4406 /* huh, this should not happen */ | 4467 /* huh, this should not happen */ |
4407#ifdef INVARIANTS 4408 panic("Flight size incorrect? fixing??"); 4409#else 4410 printf("Flight size incorrect? fixing\n"); | 4468 if (sctp_anal_print == 0) { 4469 printf("Flight size-express incorrect? cumack:%x\n", cumack); 4470 sctp_print_fs_audit(asoc); 4471 } |
4411 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 4412 net->flight_size = 0; 4413 } 4414 asoc->total_flight = 0; 4415 asoc->total_flight_count = 0; 4416 asoc->sent_queue_retran_cnt = 0; 4417 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { 4418 if (tp1->sent < SCTP_DATAGRAM_RESEND) { 4419 tp1->whoTo->flight_size += tp1->book_size; 4420 asoc->total_flight += tp1->book_size; 4421 asoc->total_flight_count++; 4422 } else if (tp1->sent == SCTP_DATAGRAM_RESEND) { 4423 asoc->sent_queue_retran_cnt++; 4424 } 4425 } | 4472 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 4473 net->flight_size = 0; 4474 } 4475 asoc->total_flight = 0; 4476 asoc->total_flight_count = 0; 4477 asoc->sent_queue_retran_cnt = 0; 4478 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { 4479 if (tp1->sent < SCTP_DATAGRAM_RESEND) { 4480 tp1->whoTo->flight_size += tp1->book_size; 4481 asoc->total_flight += tp1->book_size; 4482 asoc->total_flight_count++; 4483 } else if (tp1->sent == SCTP_DATAGRAM_RESEND) { 4484 asoc->sent_queue_retran_cnt++; 4485 } 4486 } |
4426#endif | 4487 if (sctp_anal_print == 0) { 4488 printf("After audit, totalflight:%d, retran_cnt:%d\n", 4489 asoc->total_flight, asoc->sent_queue_retran_cnt); 4490 sctp_anal_print = 1; 4491 } 4492 done_once = 1; |
4427 goto again; 4428 } 4429 /**********************************/ 4430 /* Now what about shutdown issues */ 4431 /**********************************/ 4432 if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue)) { 4433 /* nothing left on sendqueue.. consider done */ 4434 /* clean up */ --- 87 unchanged lines hidden (view full) --- 4522sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb, 4523 struct sctp_nets *net_from, int *abort_now) 4524{ 4525 struct sctp_association *asoc; 4526 struct sctp_sack *sack; 4527 struct sctp_tmit_chunk *tp1, *tp2; 4528 uint32_t cum_ack, last_tsn, biggest_tsn_acked, biggest_tsn_newly_acked, 4529 this_sack_lowest_newack; | 4493 goto again; 4494 } 4495 /**********************************/ 4496 /* Now what about shutdown issues */ 4497 /**********************************/ 4498 if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue)) { 4499 /* nothing left on sendqueue.. consider done */ 4500 /* clean up */ --- 87 unchanged lines hidden (view full) --- 4588sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb, 4589 struct sctp_nets *net_from, int *abort_now) 4590{ 4591 struct sctp_association *asoc; 4592 struct sctp_sack *sack; 4593 struct sctp_tmit_chunk *tp1, *tp2; 4594 uint32_t cum_ack, last_tsn, biggest_tsn_acked, biggest_tsn_newly_acked, 4595 this_sack_lowest_newack; |
4596 uint32_t sav_cum_ack; |
|
4530 uint16_t num_seg, num_dup; 4531 uint16_t wake_him = 0; 4532 unsigned int sack_length; 4533 uint32_t send_s; 4534 long j; 4535 int accum_moved = 0; 4536 int will_exit_fast_recovery = 0; 4537 uint32_t a_rwnd, old_rwnd; 4538 int win_probe_recovery = 0; 4539 struct sctp_nets *net = NULL; 4540 int nonce_sum_flag, ecn_seg_sums = 0; | 4597 uint16_t num_seg, num_dup; 4598 uint16_t wake_him = 0; 4599 unsigned int sack_length; 4600 uint32_t send_s; 4601 long j; 4602 int accum_moved = 0; 4603 int will_exit_fast_recovery = 0; 4604 uint32_t a_rwnd, old_rwnd; 4605 int win_probe_recovery = 0; 4606 struct sctp_nets *net = NULL; 4607 int nonce_sum_flag, ecn_seg_sums = 0; |
4608 int done_once; |
|
4541 uint8_t reneged_all = 0; 4542 uint8_t cmt_dac_flag; 4543 4544 /* 4545 * we take any chance we can to service our queues since we cannot 4546 * get awoken when the socket is read from :< 4547 */ 4548 /* --- 114 unchanged lines hidden (view full) --- 4663 } 4664 /**********************/ 4665 /* 1) check the range */ 4666 /**********************/ 4667 if (compare_with_wrap(asoc->last_acked_seq, last_tsn, MAX_TSN)) { 4668 /* acking something behind */ 4669 return; 4670 } | 4609 uint8_t reneged_all = 0; 4610 uint8_t cmt_dac_flag; 4611 4612 /* 4613 * we take any chance we can to service our queues since we cannot 4614 * get awoken when the socket is read from :< 4615 */ 4616 /* --- 114 unchanged lines hidden (view full) --- 4731 } 4732 /**********************/ 4733 /* 1) check the range */ 4734 /**********************/ 4735 if (compare_with_wrap(asoc->last_acked_seq, last_tsn, MAX_TSN)) { 4736 /* acking something behind */ 4737 return; 4738 } |
4739 sav_cum_ack = asoc->last_acked_seq; 4740 |
|
4671 /* update the Rwnd of the peer */ 4672 if (TAILQ_EMPTY(&asoc->sent_queue) && 4673 TAILQ_EMPTY(&asoc->send_queue) && 4674 (asoc->stream_queue_cnt == 0) 4675 ) { 4676 /* nothing left on send/sent and strmq */ 4677#ifdef SCTP_LOG_RWND 4678 sctp_log_rwnd_set(SCTP_SET_PEER_RWND_VIA_SACK, --- 707 unchanged lines hidden (view full) --- 5386 } 5387 if (asoc->peers_rwnd > old_rwnd) { 5388 win_probe_recovery = 1; 5389 } 5390 /* 5391 * Now we must setup so we have a timer up for anyone with 5392 * outstanding data. 5393 */ | 4741 /* update the Rwnd of the peer */ 4742 if (TAILQ_EMPTY(&asoc->sent_queue) && 4743 TAILQ_EMPTY(&asoc->send_queue) && 4744 (asoc->stream_queue_cnt == 0) 4745 ) { 4746 /* nothing left on send/sent and strmq */ 4747#ifdef SCTP_LOG_RWND 4748 sctp_log_rwnd_set(SCTP_SET_PEER_RWND_VIA_SACK, --- 707 unchanged lines hidden (view full) --- 5456 } 5457 if (asoc->peers_rwnd > old_rwnd) { 5458 win_probe_recovery = 1; 5459 } 5460 /* 5461 * Now we must setup so we have a timer up for anyone with 5462 * outstanding data. 5463 */ |
5464 done_once = 0; |
|
5394again: 5395 j = 0; 5396 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 5397 if (win_probe_recovery && (net->window_probe)) { 5398 net->window_probe = 0; 5399 /*- 5400 * Find first chunk that was used with 5401 * window probe and clear the event. Put --- 16 unchanged lines hidden (view full) --- 5418 } 5419 } 5420 if (net->flight_size) { 5421 j++; 5422 sctp_timer_start(SCTP_TIMER_TYPE_SEND, 5423 stcb->sctp_ep, stcb, net); 5424 } 5425 } | 5465again: 5466 j = 0; 5467 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 5468 if (win_probe_recovery && (net->window_probe)) { 5469 net->window_probe = 0; 5470 /*- 5471 * Find first chunk that was used with 5472 * window probe and clear the event. Put --- 16 unchanged lines hidden (view full) --- 5489 } 5490 } 5491 if (net->flight_size) { 5492 j++; 5493 sctp_timer_start(SCTP_TIMER_TYPE_SEND, 5494 stcb->sctp_ep, stcb, net); 5495 } 5496 } |
5426 if ((j == 0) && (!TAILQ_EMPTY(&asoc->sent_queue)) && (asoc->sent_queue_retran_cnt == 0)) { | 5497 if ((j == 0) && 5498 (!TAILQ_EMPTY(&asoc->sent_queue)) && 5499 (asoc->sent_queue_retran_cnt == 0) && 5500 (done_once == 0)) { |
5427 /* huh, this should not happen */ | 5501 /* huh, this should not happen */ |
5428#ifdef INVARIANTS 5429 panic("Flight size incorrect? fixing??"); 5430#else 5431 printf("Flight size incorrect? fixing??\n"); | 5502 if (sctp_anal_print == 0) { 5503 printf("Flight size incorrect sack-cumack:%x prev_last_ack:%x? fixing??", 5504 cum_ack, sav_cum_ack); 5505 sctp_print_fs_audit(asoc); 5506 } |
5432 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 5433 net->flight_size = 0; 5434 } 5435 asoc->total_flight = 0; 5436 asoc->total_flight_count = 0; 5437 asoc->sent_queue_retran_cnt = 0; 5438 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { 5439 if (tp1->sent < SCTP_DATAGRAM_RESEND) { 5440 tp1->whoTo->flight_size += tp1->book_size; 5441 asoc->total_flight += tp1->book_size; 5442 asoc->total_flight_count++; 5443 } else if (tp1->sent == SCTP_DATAGRAM_RESEND) { 5444 asoc->sent_queue_retran_cnt++; 5445 } 5446 } | 5507 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 5508 net->flight_size = 0; 5509 } 5510 asoc->total_flight = 0; 5511 asoc->total_flight_count = 0; 5512 asoc->sent_queue_retran_cnt = 0; 5513 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { 5514 if (tp1->sent < SCTP_DATAGRAM_RESEND) { 5515 tp1->whoTo->flight_size += tp1->book_size; 5516 asoc->total_flight += tp1->book_size; 5517 asoc->total_flight_count++; 5518 } else if (tp1->sent == SCTP_DATAGRAM_RESEND) { 5519 asoc->sent_queue_retran_cnt++; 5520 } 5521 } |
5447#endif | 5522 if (sctp_anal_print == 0) { 5523 printf("After audit, totalflight:%d retran count:%d\n", 5524 asoc->total_flight, asoc->sent_queue_retran_cnt); 5525 sctp_anal_print = 1; 5526 } 5527 done_once = 1; |
5448 goto again; 5449 } 5450#ifdef SCTP_SACK_RWND_LOGGING 5451 sctp_misc_ints(SCTP_SACK_RWND_UPDATE, 5452 a_rwnd, 5453 stcb->asoc.peers_rwnd, 5454 stcb->asoc.total_flight, 5455 stcb->asoc.total_output_queue_size); --- 360 unchanged lines hidden --- | 5528 goto again; 5529 } 5530#ifdef SCTP_SACK_RWND_LOGGING 5531 sctp_misc_ints(SCTP_SACK_RWND_UPDATE, 5532 a_rwnd, 5533 stcb->asoc.peers_rwnd, 5534 stcb->asoc.total_flight, 5535 stcb->asoc.total_output_queue_size); --- 360 unchanged lines hidden --- |