- 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:
Randall Stewart 2007-03-20 10:23:11 +00:00
parent d2e5427a0d
commit 62c1ff9c48
9 changed files with 33 additions and 36 deletions

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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
*/

View File

@ -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);

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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