Deleted Added
full compact
sctp_output.c (189444) sctp_output.c (189790)
1/*-
2 * Copyright (c) 2001-2008, 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_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2008, 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_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 189444 2009-03-06 11:03:52Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 189790 2009-03-14 13:42:13Z rrs $");
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
40#include <netinet/sctp_header.h>
41#include <netinet/sctp_pcb.h>
42#include <netinet/sctputil.h>

--- 7465 unchanged lines hidden (view full) ---

7508 int cause;
7509
7510 if (chk->sent > SCTP_DATAGRAM_UNSENT)
7511 cause = SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT;
7512 else
7513 cause = SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_UNSENT;
7514 ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
7515 cause,
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
40#include <netinet/sctp_header.h>
41#include <netinet/sctp_pcb.h>
42#include <netinet/sctputil.h>

--- 7465 unchanged lines hidden (view full) ---

7508 int cause;
7509
7510 if (chk->sent > SCTP_DATAGRAM_UNSENT)
7511 cause = SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT;
7512 else
7513 cause = SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_UNSENT;
7514 ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
7515 cause,
7516 &asoc->sent_queue, SCTP_SO_LOCKED);
7516 SCTP_SO_LOCKED);
7517 freed_spc += ret_spc;
7518 if (freed_spc >= dataout) {
7519 return;
7520 }
7521 } /* if chunk was present */
7522 } /* if of sufficent priority */
7523 } /* if chunk has enabled */
7524 } /* tailqforeach */

--- 8 unchanged lines hidden (view full) ---

7533 /*
7534 * We release the book_size
7535 * if the mbuf is here
7536 */
7537 int ret_spc;
7538
7539 ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
7540 SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_UNSENT,
7517 freed_spc += ret_spc;
7518 if (freed_spc >= dataout) {
7519 return;
7520 }
7521 } /* if chunk was present */
7522 } /* if of sufficent priority */
7523 } /* if chunk has enabled */
7524 } /* tailqforeach */

--- 8 unchanged lines hidden (view full) ---

7533 /*
7534 * We release the book_size
7535 * if the mbuf is here
7536 */
7537 int ret_spc;
7538
7539 ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
7540 SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_UNSENT,
7541 &asoc->send_queue, SCTP_SO_LOCKED);
7541 SCTP_SO_LOCKED);
7542
7543 freed_spc += ret_spc;
7544 if (freed_spc >= dataout) {
7545 return;
7546 }
7547 } /* end if chk->data */
7548 } /* end if right class */
7549 } /* end if chk pr-sctp */

--- 850 unchanged lines hidden (view full) ---

8400
8401 for (chk = TAILQ_FIRST(&asoc->control_send_queue);
8402 chk; chk = nchk) {
8403 nchk = TAILQ_NEXT(chk, sctp_next);
8404 if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
8405 (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK) || /* EY */
8406 (chk->rec.chunk_id.id == SCTP_HEARTBEAT_REQUEST) ||
8407 (chk->rec.chunk_id.id == SCTP_HEARTBEAT_ACK) ||
7542
7543 freed_spc += ret_spc;
7544 if (freed_spc >= dataout) {
7545 return;
7546 }
7547 } /* end if chk->data */
7548 } /* end if right class */
7549 } /* end if chk pr-sctp */

--- 850 unchanged lines hidden (view full) ---

8400
8401 for (chk = TAILQ_FIRST(&asoc->control_send_queue);
8402 chk; chk = nchk) {
8403 nchk = TAILQ_NEXT(chk, sctp_next);
8404 if ((chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) ||
8405 (chk->rec.chunk_id.id == SCTP_NR_SELECTIVE_ACK) || /* EY */
8406 (chk->rec.chunk_id.id == SCTP_HEARTBEAT_REQUEST) ||
8407 (chk->rec.chunk_id.id == SCTP_HEARTBEAT_ACK) ||
8408 (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) ||
8408 (chk->rec.chunk_id.id == SCTP_SHUTDOWN) ||
8409 (chk->rec.chunk_id.id == SCTP_SHUTDOWN_ACK) ||
8410 (chk->rec.chunk_id.id == SCTP_OPERATION_ERROR) ||
8411 (chk->rec.chunk_id.id == SCTP_PACKET_DROPPED) ||
8412 (chk->rec.chunk_id.id == SCTP_COOKIE_ACK) ||
8413 (chk->rec.chunk_id.id == SCTP_ECN_CWR) ||
8414 (chk->rec.chunk_id.id == SCTP_ASCONF_ACK)) {
8415 /* Stray chunks must be cleaned up */

--- 126 unchanged lines hidden (view full) ---

8542 }
8543 if ((sp->msg_is_complete) && (sp->length == 0)) {
8544 if (sp->sender_all_done) {
8545 /*
8546 * We are doing differed cleanup. Last time through
8547 * when we took all the data the sender_all_done was
8548 * not set.
8549 */
8409 (chk->rec.chunk_id.id == SCTP_SHUTDOWN) ||
8410 (chk->rec.chunk_id.id == SCTP_SHUTDOWN_ACK) ||
8411 (chk->rec.chunk_id.id == SCTP_OPERATION_ERROR) ||
8412 (chk->rec.chunk_id.id == SCTP_PACKET_DROPPED) ||
8413 (chk->rec.chunk_id.id == SCTP_COOKIE_ACK) ||
8414 (chk->rec.chunk_id.id == SCTP_ECN_CWR) ||
8415 (chk->rec.chunk_id.id == SCTP_ASCONF_ACK)) {
8416 /* Stray chunks must be cleaned up */

--- 126 unchanged lines hidden (view full) ---

8543 }
8544 if ((sp->msg_is_complete) && (sp->length == 0)) {
8545 if (sp->sender_all_done) {
8546 /*
8547 * We are doing differed cleanup. Last time through
8548 * when we took all the data the sender_all_done was
8549 * not set.
8550 */
8550 if (sp->put_last_out == 0) {
8551 if ((sp->put_last_out == 0) && (sp->discard_rest == 0)) {
8551 SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
8552 SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
8553 sp->sender_all_done,
8554 sp->length,
8555 sp->msg_is_complete,
8556 sp->put_last_out,
8557 send_lock_up);
8558 }

--- 4 unchanged lines hidden (view full) ---

8563 atomic_subtract_int(&asoc->stream_queue_cnt, 1);
8564 TAILQ_REMOVE(&strq->outqueue, sp, next);
8565 sctp_free_remote_addr(sp->net);
8566 if (sp->data) {
8567 sctp_m_freem(sp->data);
8568 sp->data = NULL;
8569 }
8570 sctp_free_a_strmoq(stcb, sp);
8552 SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
8553 SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
8554 sp->sender_all_done,
8555 sp->length,
8556 sp->msg_is_complete,
8557 sp->put_last_out,
8558 send_lock_up);
8559 }

--- 4 unchanged lines hidden (view full) ---

8564 atomic_subtract_int(&asoc->stream_queue_cnt, 1);
8565 TAILQ_REMOVE(&strq->outqueue, sp, next);
8566 sctp_free_remote_addr(sp->net);
8567 if (sp->data) {
8568 sctp_m_freem(sp->data);
8569 sp->data = NULL;
8570 }
8571 sctp_free_a_strmoq(stcb, sp);
8571
8572 /* we can't be locked to it */
8573 *locked = 0;
8574 stcb->asoc.locked_on_sending = NULL;
8575 if (send_lock_up) {
8576 SCTP_TCB_SEND_UNLOCK(stcb);
8577 send_lock_up = 0;
8578 }
8579 /* back to get the next msg */

--- 11 unchanged lines hidden (view full) ---

8591 } else {
8592 /* is there some to get */
8593 if (sp->length == 0) {
8594 /* no */
8595 *locked = 1;
8596 *giveup = 1;
8597 to_move = 0;
8598 goto out_of;
8572 /* we can't be locked to it */
8573 *locked = 0;
8574 stcb->asoc.locked_on_sending = NULL;
8575 if (send_lock_up) {
8576 SCTP_TCB_SEND_UNLOCK(stcb);
8577 send_lock_up = 0;
8578 }
8579 /* back to get the next msg */

--- 11 unchanged lines hidden (view full) ---

8591 } else {
8592 /* is there some to get */
8593 if (sp->length == 0) {
8594 /* no */
8595 *locked = 1;
8596 *giveup = 1;
8597 to_move = 0;
8598 goto out_of;
8599 } else if (sp->discard_rest) {
8600 if (send_lock_up == 0) {
8601 SCTP_TCB_SEND_LOCK(stcb);
8602 send_lock_up = 1;
8603 }
8604 /* Whack down the size */
8605 atomic_subtract_int(&stcb->asoc.total_output_queue_size, sp->length);
8606 if ((stcb->sctp_socket != NULL) && \
8607 ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
8608 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
8609 atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc, sp->length);
8610 }
8611 if (sp->data) {
8612 sctp_m_freem(sp->data);
8613 sp->data = NULL;
8614 sp->tail_mbuf = NULL;
8615 }
8616 sp->length = 0;
8617 sp->some_taken = 1;
8618 *locked = 1;
8619 *giveup = 1;
8620 to_move = 0;
8621 goto out_of;
8599 }
8600 }
8601 some_taken = sp->some_taken;
8602 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
8603 sp->msg_is_complete = 1;
8604 }
8605re_look:
8606 length = sp->length;

--- 2921 unchanged lines hidden (view full) ---

11528}
11529
11530void
11531send_forward_tsn(struct sctp_tcb *stcb,
11532 struct sctp_association *asoc)
11533{
11534 struct sctp_tmit_chunk *chk;
11535 struct sctp_forward_tsn_chunk *fwdtsn;
8622 }
8623 }
8624 some_taken = sp->some_taken;
8625 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
8626 sp->msg_is_complete = 1;
8627 }
8628re_look:
8629 length = sp->length;

--- 2921 unchanged lines hidden (view full) ---

11551}
11552
11553void
11554send_forward_tsn(struct sctp_tcb *stcb,
11555 struct sctp_association *asoc)
11556{
11557 struct sctp_tmit_chunk *chk;
11558 struct sctp_forward_tsn_chunk *fwdtsn;
11559 uint32_t advance_peer_ack_point;
11536
11537 SCTP_TCB_LOCK_ASSERT(stcb);
11538 TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
11539 if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) {
11540 /* mark it to unsent */
11541 chk->sent = SCTP_DATAGRAM_UNSENT;
11542 chk->snd_count = 0;
11543 /* Do we correct its output location? */

--- 61 unchanged lines hidden (view full) ---

11605 ovh = SCTP_MIN_OVERHEAD;
11606 } else {
11607 ovh = SCTP_MIN_V4_OVERHEAD;
11608 }
11609 if (cnt_of_space > (asoc->smallest_mtu - ovh)) {
11610 /* trim to a mtu size */
11611 cnt_of_space = asoc->smallest_mtu - ovh;
11612 }
11560
11561 SCTP_TCB_LOCK_ASSERT(stcb);
11562 TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
11563 if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) {
11564 /* mark it to unsent */
11565 chk->sent = SCTP_DATAGRAM_UNSENT;
11566 chk->snd_count = 0;
11567 /* Do we correct its output location? */

--- 61 unchanged lines hidden (view full) ---

11629 ovh = SCTP_MIN_OVERHEAD;
11630 } else {
11631 ovh = SCTP_MIN_V4_OVERHEAD;
11632 }
11633 if (cnt_of_space > (asoc->smallest_mtu - ovh)) {
11634 /* trim to a mtu size */
11635 cnt_of_space = asoc->smallest_mtu - ovh;
11636 }
11637 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) {
11638 sctp_misc_ints(SCTP_FWD_TSN_CHECK,
11639 0xff, 0, cnt_of_skipped,
11640 asoc->advanced_peer_ack_point);
11641
11642 }
11643 advance_peer_ack_point = asoc->advanced_peer_ack_point;
11613 if (cnt_of_space < space_needed) {
11614 /*-
11615 * ok we must trim down the chunk by lowering the
11616 * advance peer ack point.
11617 */
11644 if (cnt_of_space < space_needed) {
11645 /*-
11646 * ok we must trim down the chunk by lowering the
11647 * advance peer ack point.
11648 */
11649 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) {
11650 sctp_misc_ints(SCTP_FWD_TSN_CHECK,
11651 0xff, 0xff, cnt_of_space,
11652 space_needed);
11653 }
11618 cnt_of_skipped = (cnt_of_space -
11619 ((sizeof(struct sctp_forward_tsn_chunk)) /
11620 sizeof(struct sctp_strseq)));
11621 /*-
11622 * Go through and find the TSN that will be the one
11623 * we report.
11624 */
11625 at = TAILQ_FIRST(&asoc->sent_queue);
11626 for (i = 0; i < cnt_of_skipped; i++) {
11627 tp1 = TAILQ_NEXT(at, sctp_next);
11628 at = tp1;
11629 }
11654 cnt_of_skipped = (cnt_of_space -
11655 ((sizeof(struct sctp_forward_tsn_chunk)) /
11656 sizeof(struct sctp_strseq)));
11657 /*-
11658 * Go through and find the TSN that will be the one
11659 * we report.
11660 */
11661 at = TAILQ_FIRST(&asoc->sent_queue);
11662 for (i = 0; i < cnt_of_skipped; i++) {
11663 tp1 = TAILQ_NEXT(at, sctp_next);
11664 at = tp1;
11665 }
11666 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) {
11667 sctp_misc_ints(SCTP_FWD_TSN_CHECK,
11668 0xff, cnt_of_skipped, at->rec.data.TSN_seq,
11669 asoc->advanced_peer_ack_point);
11670 }
11630 last = at;
11631 /*-
11632 * last now points to last one I can report, update
11633 * peer ack point
11634 */
11671 last = at;
11672 /*-
11673 * last now points to last one I can report, update
11674 * peer ack point
11675 */
11635 asoc->advanced_peer_ack_point = last->rec.data.TSN_seq;
11676 advance_peer_ack_point = last->rec.data.TSN_seq;
11636 space_needed -= (cnt_of_skipped * sizeof(struct sctp_strseq));
11637 }
11638 chk->send_size = space_needed;
11639 /* Setup the chunk */
11640 fwdtsn = mtod(chk->data, struct sctp_forward_tsn_chunk *);
11641 fwdtsn->ch.chunk_length = htons(chk->send_size);
11642 fwdtsn->ch.chunk_flags = 0;
11643 fwdtsn->ch.chunk_type = SCTP_FORWARD_CUM_TSN;
11677 space_needed -= (cnt_of_skipped * sizeof(struct sctp_strseq));
11678 }
11679 chk->send_size = space_needed;
11680 /* Setup the chunk */
11681 fwdtsn = mtod(chk->data, struct sctp_forward_tsn_chunk *);
11682 fwdtsn->ch.chunk_length = htons(chk->send_size);
11683 fwdtsn->ch.chunk_flags = 0;
11684 fwdtsn->ch.chunk_type = SCTP_FORWARD_CUM_TSN;
11644 fwdtsn->new_cumulative_tsn = htonl(asoc->advanced_peer_ack_point);
11685 fwdtsn->new_cumulative_tsn = htonl(advance_peer_ack_point);
11645 chk->send_size = (sizeof(struct sctp_forward_tsn_chunk) +
11646 (cnt_of_skipped * sizeof(struct sctp_strseq)));
11647 SCTP_BUF_LEN(chk->data) = chk->send_size;
11648 fwdtsn++;
11649 /*-
11650 * Move pointer to after the fwdtsn and transfer to the
11651 * strseq pointer.
11652 */

--- 14 unchanged lines hidden (view full) ---

11667 for (i = 0; i < cnt_of_skipped; i++) {
11668 tp1 = TAILQ_NEXT(at, sctp_next);
11669 if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) {
11670 /* We don't report these */
11671 i--;
11672 at = tp1;
11673 continue;
11674 }
11686 chk->send_size = (sizeof(struct sctp_forward_tsn_chunk) +
11687 (cnt_of_skipped * sizeof(struct sctp_strseq)));
11688 SCTP_BUF_LEN(chk->data) = chk->send_size;
11689 fwdtsn++;
11690 /*-
11691 * Move pointer to after the fwdtsn and transfer to the
11692 * strseq pointer.
11693 */

--- 14 unchanged lines hidden (view full) ---

11708 for (i = 0; i < cnt_of_skipped; i++) {
11709 tp1 = TAILQ_NEXT(at, sctp_next);
11710 if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) {
11711 /* We don't report these */
11712 i--;
11713 at = tp1;
11714 continue;
11715 }
11716 if (at->rec.data.TSN_seq == advance_peer_ack_point) {
11717 at->rec.data.fwd_tsn_cnt = 0;
11718 }
11675 strseq->stream = ntohs(at->rec.data.stream_number);
11676 strseq->sequence = ntohs(at->rec.data.stream_seq);
11677 strseq++;
11678 at = tp1;
11679 }
11680 }
11681 return;
11682

--- 3924 unchanged lines hidden ---
11719 strseq->stream = ntohs(at->rec.data.stream_number);
11720 strseq->sequence = ntohs(at->rec.data.stream_seq);
11721 strseq++;
11722 at = tp1;
11723 }
11724 }
11725 return;
11726

--- 3924 unchanged lines hidden ---