- window update sacks sent incorrectly after
shutdown which caused extra abort from peer. - RTT time calculation was not being done in express sack handling since it refered to an unused variable (rto_pending). Removed variable. - socket buffer high water access macro-ized.
This commit is contained in:
parent
d2e5427a0d
commit
62c1ff9c48
@ -74,7 +74,7 @@ sctp_set_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
asoc->size_on_reasm_queue == 0 &&
|
||||
asoc->size_on_all_streams == 0) {
|
||||
/* Full rwnd granted */
|
||||
asoc->my_rwnd = max(stcb->sctp_socket->so_rcv.sb_hiwat,
|
||||
asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
|
||||
SCTP_MINIMAL_RWND);
|
||||
return;
|
||||
}
|
||||
@ -134,7 +134,7 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
asoc->size_on_reasm_queue == 0 &&
|
||||
asoc->size_on_all_streams == 0) {
|
||||
/* Full rwnd granted */
|
||||
calc = max(stcb->sctp_socket->so_rcv.sb_hiwat,
|
||||
calc = max(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
|
||||
SCTP_MINIMAL_RWND);
|
||||
return (calc);
|
||||
}
|
||||
@ -3024,7 +3024,6 @@ sctp_handle_segments(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
asoc,
|
||||
tp1->whoTo,
|
||||
&tp1->sent_rcv_time);
|
||||
tp1->whoTo->rto_pending = 0;
|
||||
tp1->do_rtt = 0;
|
||||
}
|
||||
}
|
||||
@ -3500,7 +3499,6 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
* this guy had a RTO calculation pending on
|
||||
* it, cancel it
|
||||
*/
|
||||
tp1->whoTo->rto_pending = 0;
|
||||
tp1->do_rtt = 0;
|
||||
}
|
||||
/* fix counts and things */
|
||||
@ -4171,12 +4169,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
tp1->send_size;
|
||||
|
||||
/* update RTO too? */
|
||||
if ((tp1->do_rtt) && (tp1->whoTo->rto_pending)) {
|
||||
if (tp1->do_rtt) {
|
||||
tp1->whoTo->RTO =
|
||||
sctp_calculate_rto(stcb,
|
||||
asoc, tp1->whoTo,
|
||||
&tp1->sent_rcv_time);
|
||||
tp1->whoTo->rto_pending = 0;
|
||||
tp1->do_rtt = 0;
|
||||
}
|
||||
}
|
||||
@ -4738,7 +4735,6 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
|
||||
sctp_calculate_rto(stcb,
|
||||
asoc, tp1->whoTo,
|
||||
&tp1->sent_rcv_time);
|
||||
tp1->whoTo->rto_pending = 0;
|
||||
tp1->do_rtt = 0;
|
||||
}
|
||||
}
|
||||
|
@ -2566,7 +2566,6 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
|
||||
* this guy had a RTO calculation
|
||||
* pending on it, cancel it
|
||||
*/
|
||||
tp1->whoTo->rto_pending = 0;
|
||||
tp1->do_rtt = 0;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_pdrpmark);
|
||||
|
@ -259,6 +259,9 @@ typedef struct callout sctp_os_timer_t;
|
||||
(sb).sb_mb = NULL; \
|
||||
(sb).sb_mbcnt = 0;
|
||||
|
||||
#define SCTP_SB_LIMIT_RCV(so) so->so_rcv.sb_hiwat
|
||||
#define SCTP_SB_LIMIT_SND(so) so->so_snd.sb_hiwat
|
||||
|
||||
/*
|
||||
* SCTP AUTH
|
||||
*/
|
||||
|
@ -3953,7 +3953,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
/* place in my tag */
|
||||
initm->msg.init.initiate_tag = htonl(stcb->asoc.my_vtag);
|
||||
/* set up some of the credits. */
|
||||
initm->msg.init.a_rwnd = htonl(max(inp->sctp_socket->so_rcv.sb_hiwat,
|
||||
initm->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket),
|
||||
SCTP_MINIMAL_RWND));
|
||||
|
||||
initm->msg.init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
|
||||
@ -4862,7 +4862,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
stc.my_vtag = initackm_out->msg.init.initiate_tag;
|
||||
|
||||
/* set up some of the credits. */
|
||||
initackm_out->msg.init.a_rwnd = htonl(max(inp->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND));
|
||||
initackm_out->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND));
|
||||
/* set what I want */
|
||||
his_limit = ntohs(init_chk->init.num_inbound_streams);
|
||||
/* choose what I want */
|
||||
@ -7314,15 +7314,10 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
||||
*num_out += (ctl_cnt + bundle_at);
|
||||
}
|
||||
if (bundle_at) {
|
||||
/* if (!net->rto_pending) { */
|
||||
/* setup for a RTO measurement */
|
||||
/* net->rto_pending = 1; */
|
||||
tsns_sent = data_list[0]->rec.data.TSN_seq;
|
||||
|
||||
data_list[0]->do_rtt = 1;
|
||||
/* } else { */
|
||||
/* data_list[0]->do_rtt = 0; */
|
||||
/* } */
|
||||
SCTP_STAT_INCR_BY(sctps_senddata, bundle_at);
|
||||
sctp_clean_up_datalist(stcb, asoc, data_list, bundle_at, net);
|
||||
if (sctp_early_fr) {
|
||||
@ -9625,7 +9620,7 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
|
||||
chk->rec.chunk_id.can_take_data = 1;
|
||||
drp->ch.chunk_type = SCTP_PACKET_DROPPED;
|
||||
drp->ch.chunk_length = htons(chk->send_size);
|
||||
spc = stcb->sctp_socket->so_rcv.sb_hiwat;
|
||||
spc = SCTP_SB_LIMIT_RCV(stcb->sctp_socket);
|
||||
if (spc < 0) {
|
||||
spc = 0;
|
||||
}
|
||||
@ -10416,7 +10411,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
|
||||
*error = 0;
|
||||
/* Unless E_EOR mode is on, we must make a send FIT in one call. */
|
||||
if (((user_marks_eor == 0) && non_blocking) &&
|
||||
(uio->uio_resid > stcb->sctp_socket->so_snd.sb_hiwat)) {
|
||||
(uio->uio_resid > SCTP_SB_LIMIT_SND(stcb->sctp_socket))) {
|
||||
/* It will NEVER fit */
|
||||
*error = EMSGSIZE;
|
||||
goto out_now;
|
||||
@ -10828,7 +10823,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
asoc = &stcb->asoc;
|
||||
/* would we block? */
|
||||
if (non_blocking) {
|
||||
if ((so->so_snd.sb_hiwat <
|
||||
if ((SCTP_SB_LIMIT_SND(so) <
|
||||
(sndlen + stcb->asoc.total_output_queue_size)) ||
|
||||
(stcb->asoc.chunks_on_out_queue >
|
||||
sctp_max_chunks_on_queue)) {
|
||||
@ -10997,8 +10992,8 @@ sctp_lower_sosend(struct socket *so,
|
||||
goto out_unlocked;
|
||||
}
|
||||
/* Calculate the maximum we can send */
|
||||
if (so->so_snd.sb_hiwat > stcb->asoc.total_output_queue_size) {
|
||||
max_len = so->so_snd.sb_hiwat - stcb->asoc.total_output_queue_size;
|
||||
if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size) {
|
||||
max_len = SCTP_SB_LIMIT_SND(so) - stcb->asoc.total_output_queue_size;
|
||||
} else {
|
||||
max_len = 0;
|
||||
}
|
||||
@ -11021,7 +11016,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
if (max_len < sctp_add_more_threshold) {
|
||||
/* No room right no ! */
|
||||
SOCKBUF_LOCK(&so->so_snd);
|
||||
while (so->so_snd.sb_hiwat < (stcb->asoc.total_output_queue_size + sctp_add_more_threshold)) {
|
||||
while (SCTP_SB_LIMIT_SND(so) < (stcb->asoc.total_output_queue_size + sctp_add_more_threshold)) {
|
||||
#ifdef SCTP_BLK_LOGGING
|
||||
sctp_log_block(SCTP_BLOCK_LOG_INTO_BLKA,
|
||||
so, asoc, uio->uio_resid);
|
||||
@ -11049,8 +11044,8 @@ sctp_lower_sosend(struct socket *so,
|
||||
goto out_unlocked;
|
||||
}
|
||||
}
|
||||
if (so->so_snd.sb_hiwat > stcb->asoc.total_output_queue_size) {
|
||||
max_len = so->so_snd.sb_hiwat - stcb->asoc.total_output_queue_size;
|
||||
if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size) {
|
||||
max_len = SCTP_SB_LIMIT_SND(so) - stcb->asoc.total_output_queue_size;
|
||||
} else {
|
||||
max_len = 0;
|
||||
}
|
||||
@ -11143,8 +11138,8 @@ sctp_lower_sosend(struct socket *so,
|
||||
/* How much room do we have? */
|
||||
struct mbuf *new_tail, *mm;
|
||||
|
||||
if (so->so_snd.sb_hiwat > stcb->asoc.total_output_queue_size)
|
||||
max_len = so->so_snd.sb_hiwat - stcb->asoc.total_output_queue_size;
|
||||
if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size)
|
||||
max_len = SCTP_SB_LIMIT_SND(so) - stcb->asoc.total_output_queue_size;
|
||||
else
|
||||
max_len = 0;
|
||||
|
||||
@ -11213,8 +11208,8 @@ sctp_lower_sosend(struct socket *so,
|
||||
hold_tcblock = 1;
|
||||
}
|
||||
sctp_prune_prsctp(stcb, asoc, srcv, sndlen);
|
||||
if (so->so_snd.sb_hiwat > stcb->asoc.total_output_queue_size)
|
||||
max_len = so->so_snd.sb_hiwat - stcb->asoc.total_output_queue_size;
|
||||
if (SCTP_SB_LIMIT_SND(so) > stcb->asoc.total_output_queue_size)
|
||||
max_len = SCTP_SB_LIMIT_SND(so) - stcb->asoc.total_output_queue_size;
|
||||
else
|
||||
max_len = 0;
|
||||
if (max_len > 0) {
|
||||
@ -11338,7 +11333,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
* will get to sleep safely with the wakeup flag in
|
||||
* place.
|
||||
*/
|
||||
if (so->so_snd.sb_hiwat < (stcb->asoc.total_output_queue_size + sctp_add_more_threshold)) {
|
||||
if (SCTP_SB_LIMIT_SND(so) < (stcb->asoc.total_output_queue_size + sctp_add_more_threshold)) {
|
||||
#ifdef SCTP_BLK_LOGGING
|
||||
sctp_log_block(SCTP_BLOCK_LOG_INTO_BLK,
|
||||
so, asoc, uio->uio_resid);
|
||||
|
@ -1636,7 +1636,7 @@ sctp_inpcb_alloc(struct socket *so)
|
||||
inp->sctp_socket = so;
|
||||
inp->ip_inp.inp.inp_socket = so;
|
||||
|
||||
inp->partial_delivery_point = so->so_rcv.sb_hiwat >> SCTP_PARTIAL_DELIVERY_SHIFT;
|
||||
inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT;
|
||||
inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
|
||||
|
||||
#ifdef IPSEC
|
||||
|
@ -237,8 +237,6 @@ struct sctp_nets {
|
||||
uint8_t will_exit_fast_recovery;
|
||||
/* Flags that probably can be combined into dest_state */
|
||||
uint8_t rto_variance_dir; /* increase = 1, decreasing = 0 */
|
||||
uint8_t rto_pending; /* is segment marked for RTO update ** if we
|
||||
* split? */
|
||||
uint8_t fast_retran_ip; /* fast retransmit in progress */
|
||||
uint8_t hb_responded;
|
||||
uint8_t saw_newack; /* CMT's SFR algorithm flag */
|
||||
|
@ -524,7 +524,6 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
|
||||
*/
|
||||
orig_rwnd = stcb->asoc.peers_rwnd;
|
||||
orig_flight = net->flight_size;
|
||||
net->rto_pending = 0;
|
||||
net->fast_retran_ip = 0;
|
||||
/* Now on to each chunk */
|
||||
num_mk = cnt_mk = 0;
|
||||
|
@ -2422,6 +2422,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
uint32_t *value;
|
||||
|
||||
SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
|
||||
if (*value > SCTP_SB_LIMIT_RCV(so)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
inp->partial_delivery_point = *value;
|
||||
}
|
||||
break;
|
||||
|
@ -1024,8 +1024,8 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
|
||||
asoc->ipv6_addr_legal = 0;
|
||||
}
|
||||
|
||||
asoc->my_rwnd = max(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND);
|
||||
asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat;
|
||||
asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(m->sctp_socket), SCTP_MINIMAL_RWND);
|
||||
asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(m->sctp_socket);
|
||||
|
||||
asoc->smallest_mtu = m->sctp_frag_point;
|
||||
asoc->minrto = m->sctp_ep.sctp_minrto;
|
||||
@ -4354,7 +4354,10 @@ sctp_user_rcvd(struct sctp_tcb *stcb, int *freed_so_far, int hold_rlock,
|
||||
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
|
||||
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
|
||||
if (stcb->asoc.state & (SCTP_STATE_ABOUT_TO_BE_FREED |
|
||||
SCTP_STATE_SHUTDOWN_RECEIVED |
|
||||
SCTP_STATE_SHUTDOWN_ACK_SENT)
|
||||
) {
|
||||
/* Pre-check If we are freeing no update */
|
||||
goto no_lock;
|
||||
}
|
||||
@ -4504,7 +4507,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
if (inp == NULL) {
|
||||
return (EFAULT);
|
||||
}
|
||||
rwnd_req = (so->so_rcv.sb_hiwat >> SCTP_RWND_HIWAT_SHIFT);
|
||||
rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT);
|
||||
/* Must be at least a MTU's worth */
|
||||
if (rwnd_req < SCTP_MIN_RWND)
|
||||
rwnd_req = SCTP_MIN_RWND;
|
||||
|
Loading…
Reference in New Issue
Block a user