diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/sctp_auth.c | 9 | ||||
-rw-r--r-- | sys/netinet/sctp_constants.h | 1 | ||||
-rw-r--r-- | sys/netinet/sctp_header.h | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_indata.c | 39 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 11 | ||||
-rw-r--r-- | sys/netinet/sctp_sysctl.c | 9 | ||||
-rw-r--r-- | sys/netinet/sctp_uio.h | 3 |
7 files changed, 44 insertions, 30 deletions
diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index 07dbf8b..1c9d528 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -542,7 +542,7 @@ sctp_insert_sharedkey(struct sctp_keyhead *shared_keys, } } /* shouldn't reach here */ - return (0); + return (EINVAL); } void @@ -622,8 +622,11 @@ sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest) LIST_FOREACH(skey, src, next) { new_skey = sctp_copy_sharedkey(skey); if (new_skey != NULL) { - (void)sctp_insert_sharedkey(dest, new_skey); - count++; + if (sctp_insert_sharedkey(dest, new_skey)) { + sctp_free_sharedkey(new_skey); + } else { + count++; + } } } return (count); diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index a58c206..ecde4fe 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -345,6 +345,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_RTT_FROM_NON_DATA 0 #define SCTP_RTT_FROM_DATA 1 +#define PR_SCTP_UNORDERED_FLAG 0x0001 /* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */ #define SCTP_FIRST_MBUF_RESV 68 diff --git a/sys/netinet/sctp_header.h b/sys/netinet/sctp_header.h index 850290d..3f4948d 100644 --- a/sys/netinet/sctp_header.h +++ b/sys/netinet/sctp_header.h @@ -397,7 +397,7 @@ struct sctp_strseq { struct sctp_strseq_mid { uint16_t stream; - uint16_t reserved; + uint16_t flags; uint32_t msg_id; }; diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 7a2f42c..357a047 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -753,7 +753,7 @@ sctp_handle_old_data(struct sctp_tcb *stcb, struct sctp_association *asoc, struc */ struct sctp_tmit_chunk *chk, *lchk, *tchk; uint32_t fsn; - struct sctp_queued_to_read *nc = NULL; + struct sctp_queued_to_read *nc; int cnt_added; if (control->first_frag_seen == 0) { @@ -768,6 +768,11 @@ restart: TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, lchk) { if (chk->rec.data.fsn_num == fsn) { /* Ok lets add it */ + sctp_alloc_a_readq(stcb, nc); + if (nc == NULL) { + break; + } + memset(nc, 0, sizeof(struct sctp_queued_to_read)); TAILQ_REMOVE(&control->reasm, chk, sctp_next); sctp_add_chk_to_control(control, strm, stcb, asoc, chk); fsn++; @@ -781,7 +786,6 @@ restart: * on the control queue to a new * control. */ - sctp_alloc_a_readq(stcb, nc); sctp_build_readq_entry_from_ctl(nc, control); tchk = TAILQ_FIRST(&control->reasm); if (tchk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) { @@ -819,6 +823,7 @@ restart: if (control->on_strm_q) { TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); control->on_strm_q = 0; + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); } if (control->on_read_q == 0) { sctp_add_to_readq(stcb->sctp_ep, stcb, control, @@ -826,16 +831,19 @@ restart: SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); } sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); - if ((nc) && (nc->first_frag_seen)) { + if ((nc->first_frag_seen) && !TAILQ_EMPTY(&nc->reasm)) { /* * Switch to the new guy and * continue */ control = nc; - nc = NULL; goto restart; + } else { + sctp_free_a_readq(stcb, nc); } return (1); + } else { + sctp_free_a_readq(stcb, nc); } } else { /* Can't add more */ @@ -961,11 +969,6 @@ place_chunk: * should not happen since the FSN is a TSN and it * should have been dropped earlier. */ - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } - sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); sctp_abort_in_reasm(stcb, control, chk, abort_flag, SCTP_FROM_SCTP_INDATA + SCTP_LOC_5); @@ -1026,6 +1029,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc, s control, control->on_strm_q); } #endif + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); control->on_strm_q = 0; } @@ -1080,6 +1084,7 @@ done_un: control, control->on_strm_q); } #endif + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); TAILQ_REMOVE(&strm->inqueue, control, next_instrm); control->on_strm_q = 0; } @@ -1125,6 +1130,7 @@ deliver_more: control, control->on_strm_q); } #endif + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); TAILQ_REMOVE(&strm->inqueue, control, next_instrm); control->on_strm_q = 0; } @@ -5277,10 +5283,11 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb, } } + static void sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb, struct sctp_association *asoc, - uint16_t stream, uint32_t seq) + uint16_t stream, uint32_t seq, int ordered, int old) { struct sctp_queued_to_read *control; struct sctp_stream_in *strm; @@ -5295,7 +5302,7 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb, * queue. */ strm = &asoc->strmin[stream]; - control = find_reasm_entry(strm, (uint32_t) seq, 0, 0); + control = find_reasm_entry(strm, (uint32_t) seq, ordered, old); if (control == NULL) { /* Not found */ return; @@ -5427,6 +5434,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, unsigned int num_str; uint32_t sequence; uint16_t stream; + uint16_t ordered, flags; int old; struct sctp_strseq *stseq, strseqbuf; struct sctp_strseq_mid *stseq_m, strseqbuf_m; @@ -5452,6 +5460,12 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, } stream = ntohs(stseq_m->stream); sequence = ntohl(stseq_m->msg_id); + flags = ntohs(stseq_m->flags); + if (flags & PR_SCTP_UNORDERED_FLAG) { + ordered = 0; + } else { + ordered = 1; + } } else { stseq = (struct sctp_strseq *)sctp_m_getptr(m, offset, sizeof(struct sctp_strseq), @@ -5462,6 +5476,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, } stream = ntohs(stseq->stream); sequence = (uint32_t) ntohs(stseq->sequence); + ordered = 1; } /* Convert */ @@ -5487,7 +5502,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, asoc->fragmented_delivery_inprogress = 0; } strm = &asoc->strmin[stream]; - sctp_flush_reassm_for_str_seq(stcb, asoc, stream, sequence); + sctp_flush_reassm_for_str_seq(stcb, asoc, stream, sequence, ordered, old); TAILQ_FOREACH(ctl, &stcb->sctp_ep->read_queue, next) { if ((ctl->sinfo_stream == stream) && (ctl->sinfo_ssn == sequence)) { diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index d8c3cae..1ad3d0c 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -10383,7 +10383,7 @@ sctp_fill_in_rest: /* no more to look at */ break; } - if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) { + if ((at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) && old) { /* We don't report these */ continue; } @@ -10504,7 +10504,7 @@ sctp_fill_in_rest: tp1 = TAILQ_NEXT(at, sctp_next); if (tp1 == NULL) break; - if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) { + if (old && (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) { /* We don't report these */ i--; at = tp1; @@ -10519,8 +10519,11 @@ sctp_fill_in_rest: strseq++; } else { strseq_m->stream = ntohs(at->rec.data.stream_number); - strseq_m->reserved = ntohs(0); strseq_m->msg_id = ntohl(at->rec.data.stream_seq); + if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) + strseq_m->flags = ntohs(PR_SCTP_UNORDERED_FLAG); + else + strseq_m->flags = 0; strseq_m++; } at = tp1; @@ -11937,7 +11940,6 @@ sctp_send_deferred_reset_response(struct sctp_tcb *stcb, return; } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); - sctp_add_stream_reset_result(chk, ent->seq, response); /* setup chunk parameters */ chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; @@ -11952,6 +11954,7 @@ sctp_send_deferred_reset_response(struct sctp_tcb *stcb, ch->chunk_length = htons(chk->book_size); atomic_add_int(&chk->whoTo->ref_count, 1); SCTP_BUF_LEN(chk->data) = chk->send_size; + sctp_add_stream_reset_result(chk, ent->seq, response); /* insert the chunk for sending */ TAILQ_INSERT_TAIL(&asoc->control_send_queue, chk, diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c index aeb2e10..de21941 100644 --- a/sys/netinet/sctp_sysctl.c +++ b/sys/netinet/sctp_sysctl.c @@ -279,15 +279,6 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; - if (sin6->sin6_scope_id == 0) { - /* - * bad link - * local - * address - */ - if (sa6_recoverscope(sin6) != 0) - continue; - } } if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) continue; diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index c7e441d..e65b7b5 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -259,7 +259,8 @@ struct sctp_snd_all_completes { /* The lower four bits is an enumeration of PR-SCTP policies */ #define SCTP_PR_SCTP_NONE 0x0000/* Reliable transfer */ #define SCTP_PR_SCTP_TTL 0x0001/* Time based PR-SCTP */ -#define SCTP_PR_SCTP_BUF 0x0002/* Buffer based PR-SCTP */ +#define SCTP_PR_SCTP_PRIO 0x0002/* Buffer based PR-SCTP */ +#define SCTP_PR_SCTP_BUF SCTP_PR_SCTP_PRIO /* For backwards compatibility */ #define SCTP_PR_SCTP_RTX 0x0003/* Number of retransmissions based PR-SCTP */ #define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX #define SCTP_PR_SCTP_ALL 0x000f/* Used for aggregated stats */ |