-Improvement: Add '\n' on debug output in sctp_lower_sosend().
-Improvement: panic() on INVARIANTS kernels if memory allocation fails for a tagblock in sctp_add_vtag_to_timewait(). -Bugfix: Protect code in sctp_is_in_timewait() by SCTP_INP_INFO_WLOCK/SCTP_INP_INFO_WUNLOCK. -Cleanup: Get rid of unused variable now in sctp_init_asoc(). -Bugfix: Reuse the correct vtag in sctp_add_vtag_to_timewait(). -Cleanup: Get rid of unused constant SCTP_TIME_WAIT_SHORT in sctp_constants.h. -Improvement: Use all hash buckets of the vtag hash table. -Cleanup: Get rid of then unused constant SCTP_STACK_VTAG_HASH_SIZE_A. -Bugfix: Handle SHUTDOWN;SACK packet correctly. -Bugfix: Last TSN in a gap ack block was not being "ack'd" in the internal scoreboard. Obtained from: (with help from Michael Tuexen)
This commit is contained in:
parent
7d4723c325
commit
a1e132720b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=184883
@ -1001,8 +1001,7 @@ __FBSDID("$FreeBSD$");
|
||||
* entries must be searched to see if the tag is in timed wait. If so we
|
||||
* reject it.
|
||||
*/
|
||||
#define SCTP_STACK_VTAG_HASH_SIZE 31
|
||||
#define SCTP_STACK_VTAG_HASH_SIZE_A 32
|
||||
#define SCTP_STACK_VTAG_HASH_SIZE 32
|
||||
|
||||
|
||||
/*
|
||||
@ -1016,12 +1015,6 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#define SCTP_TIME_WAIT 60
|
||||
|
||||
/* This time wait is the same as the default cookie life
|
||||
* since we now enter a tag in every time we send a cookie.
|
||||
* We want this shorter to avoid vtag depletion.
|
||||
*/
|
||||
#define SCTP_TIME_WAIT_SHORT 60
|
||||
|
||||
/* The system retains a cache of free chunks such to
|
||||
* cut down on calls the memory allocation system. There
|
||||
* is a per association limit of free items and a overall
|
||||
|
@ -2766,8 +2766,8 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
|
||||
struct sctp_sack *sack;
|
||||
struct sctp_gap_ack_block *frag, block;
|
||||
struct sctp_tmit_chunk *tp1;
|
||||
int i;
|
||||
unsigned int j;
|
||||
int i, j;
|
||||
unsigned int theTSN;
|
||||
int num_frs = 0;
|
||||
|
||||
uint16_t frag_strt, frag_end, primary_flag_set;
|
||||
@ -2835,7 +2835,8 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
|
||||
}
|
||||
last_frag_high = frag_end + last_tsn;
|
||||
}
|
||||
for (j = frag_strt + last_tsn; (compare_with_wrap((frag_end + last_tsn), j, MAX_TSN)); j++) {
|
||||
for (j = frag_strt; j <= frag_end; j++) {
|
||||
theTSN = j + last_tsn;
|
||||
while (tp1) {
|
||||
if (tp1->rec.data.doing_fast_retransmit)
|
||||
num_frs++;
|
||||
@ -2858,7 +2859,7 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
|
||||
tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.TSN_seq;
|
||||
tp1->whoTo->find_rtx_pseudo_cumack = 0;
|
||||
}
|
||||
if (tp1->rec.data.TSN_seq == j) {
|
||||
if (tp1->rec.data.TSN_seq == theTSN) {
|
||||
if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
|
||||
/*
|
||||
* must be held until
|
||||
@ -3030,8 +3031,8 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
|
||||
}
|
||||
}
|
||||
break;
|
||||
} /* if (tp1->TSN_seq == j) */
|
||||
if (compare_with_wrap(tp1->rec.data.TSN_seq, j,
|
||||
} /* if (tp1->TSN_seq == theTSN) */
|
||||
if (compare_with_wrap(tp1->rec.data.TSN_seq, theTSN,
|
||||
MAX_TSN))
|
||||
break;
|
||||
|
||||
|
@ -4280,7 +4280,6 @@ __attribute__((noinline))
|
||||
|
||||
if ((stcb == NULL) || (chk_length < sizeof(struct sctp_sack_chunk))) {
|
||||
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on sack chunk, too small\n");
|
||||
ignore_sack:
|
||||
*offset = length;
|
||||
if (locked_tcb) {
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
@ -4293,7 +4292,7 @@ __attribute__((noinline))
|
||||
* attention to a sack sent in to us since
|
||||
* we don't care anymore.
|
||||
*/
|
||||
goto ignore_sack;
|
||||
break;
|
||||
}
|
||||
sack = (struct sctp_sack_chunk *)ch;
|
||||
nonce_sum_flag = ch->chunk_flags & SCTP_SACK_NONCE_SUM;
|
||||
|
@ -4196,6 +4196,7 @@ sctp_is_in_timewait(uint32_t tag)
|
||||
int found = 0;
|
||||
int i;
|
||||
|
||||
SCTP_INP_INFO_WLOCK();
|
||||
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
|
||||
if (!SCTP_LIST_EMPTY(chain)) {
|
||||
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
|
||||
@ -4209,6 +4210,7 @@ sctp_is_in_timewait(uint32_t tag)
|
||||
break;
|
||||
}
|
||||
}
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return (found);
|
||||
}
|
||||
|
||||
@ -4241,8 +4243,8 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time)
|
||||
twait_block->vtag_block[i].v_tag = 0;
|
||||
if (set == 0) {
|
||||
/* Reuse it for my new tag */
|
||||
twait_block->vtag_block[0].tv_sec_at_expire = now.tv_sec + time;
|
||||
twait_block->vtag_block[0].v_tag = tag;
|
||||
twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
|
||||
twait_block->vtag_block[i].v_tag = tag;
|
||||
set = 1;
|
||||
}
|
||||
}
|
||||
@ -4261,6 +4263,9 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time)
|
||||
SCTP_MALLOC(twait_block, struct sctp_tagblock *,
|
||||
sizeof(struct sctp_tagblock), SCTP_M_TIMW);
|
||||
if (twait_block == NULL) {
|
||||
#ifdef INVARIANTS
|
||||
panic("Can not alloc tagblock");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
memset(twait_block, 0, sizeof(struct sctp_tagblock));
|
||||
@ -5397,7 +5402,7 @@ sctp_pcb_init()
|
||||
SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer));
|
||||
|
||||
/* Init the TIMEWAIT list */
|
||||
for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE_A; i++) {
|
||||
for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
|
||||
LIST_INIT(&SCTP_BASE_INFO(vtag_timewait[i]));
|
||||
}
|
||||
|
||||
@ -5467,7 +5472,7 @@ sctp_pcb_finish(void)
|
||||
* free the TIMEWAIT list elements malloc'd in the function
|
||||
* sctp_add_vtag_to_timewait()...
|
||||
*/
|
||||
for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE_A; i++) {
|
||||
for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
|
||||
chain = &SCTP_BASE_INFO(vtag_timewait)[i];
|
||||
if (!SCTP_LIST_EMPTY(chain)) {
|
||||
prev_twait_block = NULL;
|
||||
|
@ -228,7 +228,7 @@ struct sctp_epinfo {
|
||||
uint32_t ipi_free_strmoq;
|
||||
|
||||
|
||||
struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE_A];
|
||||
struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE];
|
||||
|
||||
/* address work queue handling */
|
||||
#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
|
||||
|
@ -910,9 +910,6 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
||||
#endif
|
||||
asoc->sb_send_resv = 0;
|
||||
if (override_tag) {
|
||||
struct timeval now;
|
||||
|
||||
(void)SCTP_GETTIME_TIMEVAL(&now);
|
||||
if (sctp_is_in_timewait(override_tag)) {
|
||||
/*
|
||||
* It must be in the time-wait hash, we put it there
|
||||
@ -1466,6 +1463,9 @@ sctp_timeout_handler(void *t)
|
||||
SCTP_INP_INCR_REF(inp);
|
||||
if ((inp->sctp_socket == 0) &&
|
||||
((tmr->type != SCTP_TIMER_TYPE_INPKILL) &&
|
||||
(tmr->type != SCTP_TIMER_TYPE_SEND) &&
|
||||
(tmr->type != SCTP_TIMER_TYPE_RECV) &&
|
||||
(tmr->type != SCTP_TIMER_TYPE_HEARTBEAT) &&
|
||||
(tmr->type != SCTP_TIMER_TYPE_SHUTDOWN) &&
|
||||
(tmr->type != SCTP_TIMER_TYPE_SHUTDOWNACK) &&
|
||||
(tmr->type != SCTP_TIMER_TYPE_SHUTDOWNGUARD) &&
|
||||
|
Loading…
Reference in New Issue
Block a user