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 --- |