diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 36bace92572e..57867820bdde 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -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; } } diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 86634a9dc4d7..2317ceaf5da1 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -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); diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index 690036338ec4..e1b7a1f61207 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -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 */ diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 4c20802ceef6..b23edb389622 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -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 @@ again_one_more_time: *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 @@ jump_out: 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); diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 26e0d59a4a02..b2197e3609af 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -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 diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 6830b13eb44a..d57e3a0053c9 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -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 */ diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 1d6902ef50e6..a075e8ecceef 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -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; diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 82c952ecd303..98996718d4e1 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -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; diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index ea7a830ef278..aa84b982f192 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -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;