Deleted Added
full compact
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 ---