author | Randell Jesup <rjesup@jesup.org> |
Thu, 26 Mar 2015 17:15:43 -0400 | |
changeset 266332 | 1ee51b896998fa22c14a06d3e97f1a8e159538b4 |
parent 266331 | c297ede37ac5ed5d6f3be298d0355ed3bbc2ab90 |
child 266333 | 1d2301ec8a53d88275d759937fb3bd13d96dd607 |
push id | 830 |
push user | raliiev@mozilla.com |
push date | Fri, 19 Jun 2015 19:24:37 +0000 |
treeherder | mozilla-release@932614382a68 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jesup |
bugs | 1146096 |
milestone | 39.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/sctp/sctp_update.log +++ b/netwerk/sctp/sctp_update.log @@ -10,8 +10,9 @@ sctp updated to version 8131 from SVN on sctp updated to version 8165 from SVN on Wed Sep 5 09:39:43 EDT 2012 sctp updated to version 8176 from SVN on Wed Sep 5 18:02:08 EDT 2012 sctp updated to version 8263 from SVN on Sun Sep 16 00:48:48 EDT 2012 sctp updated to version 8279 from SVN on Thu Sep 20 18:19:24 EDT 2012 sctp updated to version 8397 from SVN on Wed Jan 9 00:41:16 EST 2013 sctp updated to version 8443 from SVN on Sun Mar 31 09:05:07 EDT 2013 sctp updated to version 8815 from SVN on Tue Mar 4 08:50:51 EST 2014 sctp updated to version 9168 from SVN on Tue Mar 3 12:11:40 EST 2015 +sctp updated to version 9209 from SVN on Tue Mar 24 18:11:59 EDT 2015
--- a/netwerk/sctp/src/netinet/sctp.h +++ b/netwerk/sctp/src/netinet/sctp.h @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269945 2014-08-13 15:50:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 279859 2015-03-10 19:49:25Z tuexen $"); #endif #ifndef _NETINET_SCTP_H_ #define _NETINET_SCTP_H_ #if (defined(__APPLE__) || defined(__Userspace_os_Linux) || defined(__Userspace_os_Darwin)) #include <stdint.h> #endif @@ -133,16 +133,17 @@ struct sctp_paramhdr { #define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024 #define SCTP_ECN_SUPPORTED 0x00000025 #define SCTP_PR_SUPPORTED 0x00000026 #define SCTP_AUTH_SUPPORTED 0x00000027 #define SCTP_ASCONF_SUPPORTED 0x00000028 #define SCTP_RECONFIG_SUPPORTED 0x00000029 #define SCTP_NRSACK_SUPPORTED 0x00000030 #define SCTP_PKTDROP_SUPPORTED 0x00000031 +#define SCTP_MAX_CWND 0x00000032 /* * read-only options */ #define SCTP_STATUS 0x00000100 #define SCTP_GET_PEER_ADDR_INFO 0x00000101 /* authentication support */ #define SCTP_PEER_AUTH_CHUNKS 0x00000102
--- a/netwerk/sctp/src/netinet/sctp_bsd_addr.c +++ b/netwerk/sctp/src/netinet/sctp_bsd_addr.c @@ -43,24 +43,19 @@ #include <netinet/sctp_output.h> #include <netinet/sctp_bsd_addr.h> #include <netinet/sctp_uio.h> #include <netinet/sctputil.h> #include <netinet/sctp_timer.h> #include <netinet/sctp_asconf.h> #include <netinet/sctp_sysctl.h> #include <netinet/sctp_indata.h> -#if defined(ANDROID) -#include <unistd.h> -#include <ifaddrs-android-ext.h> -#else #if defined(__FreeBSD__) #include <sys/unistd.h> #endif -#endif /* Declare all of our malloc named types */ #ifndef __Panda__ MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor"); MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array"); MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array"); MALLOC_DEFINE(SCTP_M_ASC_ADDR, "sctp_aadr", "sctp asconf address"); MALLOC_DEFINE(SCTP_M_ASC_IT, "sctp_a_it", "sctp asconf iterator");
--- a/netwerk/sctp/src/netinet/sctp_cc_functions.c +++ b/netwerk/sctp/src/netinet/sctp_cc_functions.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 271672 2014-09-16 13:48:46Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 279859 2015-03-10 19:49:25Z tuexen $"); #endif #include <netinet/sctp_os.h> #include <netinet/sctp_var.h> #include <netinet/sctp_sysctl.h> #include <netinet/sctp_pcb.h> #include <netinet/sctp_header.h> #include <netinet/sctputil.h> @@ -52,16 +52,29 @@ #include <netinet/sctp_dtrace_declare.h> #endif #define SHIFT_MPTCP_MULTI_N 40 #define SHIFT_MPTCP_MULTI_Z 16 #define SHIFT_MPTCP_MULTI 8 static void +sctp_enforce_cwnd_limit(struct sctp_association *assoc, struct sctp_nets *net) +{ + if ((assoc->max_cwnd > 0) && + (net->cwnd > assoc->max_cwnd) && + (net->cwnd > (net->mtu - sizeof(struct sctphdr)))) { + net->cwnd = assoc->max_cwnd ; + if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) { + net->cwnd = net->mtu - sizeof(struct sctphdr); + } + } +} + +static void sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) { struct sctp_association *assoc; uint32_t cwnd_in_mtu; assoc = &stcb->asoc; cwnd_in_mtu = SCTP_BASE_SYSCTL(sctp_initial_cwnd); if (cwnd_in_mtu == 0) { @@ -79,16 +92,17 @@ sctp_set_initial_cc_param(struct sctp_tc if ((stcb->asoc.sctp_cmt_on_off == SCTP_CMT_RPV1) || (stcb->asoc.sctp_cmt_on_off == SCTP_CMT_RPV2)) { /* In case of resource pooling initialize appropriately */ net->cwnd /= assoc->numnets; if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) { net->cwnd = net->mtu - sizeof(struct sctphdr); } } + sctp_enforce_cwnd_limit(assoc, net); net->ssthresh = assoc->peers_rwnd; #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE(sctp, cwnd, net, init, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, 0, net->cwnd); #endif if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE|SCTP_CWND_LOGGING_ENABLE)) { @@ -174,16 +188,17 @@ sctp_cwnd_update_after_fr(struct sctp_tc } } else { net->ssthresh = net->cwnd / 2; if (net->ssthresh < (net->mtu * 2)) { net->ssthresh = 2 * net->mtu; } } net->cwnd = net->ssthresh; + sctp_enforce_cwnd_limit(asoc, net); #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE(sctp, cwnd, net, fr, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, old_cwnd, net->cwnd); #endif if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_FR); @@ -295,17 +310,17 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UN net->cc_mod.rtcc.vol_reduce++; } else { net->cc_mod.rtcc.step_cnt = 0; } } } return (1); } - if (net->rtt < net->cc_mod.rtcc.lbw_rtt-rtt_offset) { + if (net->rtt < net->cc_mod.rtcc.lbw_rtt-rtt_offset) { /* * rtt decreased, there could be more room. * we update both the bw and the rtt here to * lock this in as a good step down. */ #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 /* Probe point 6 */ probepoint |= ((6 << 16) | 0); @@ -456,16 +471,17 @@ cc_bw_decrease(struct sctp_tcb *stcb SCT probepoint); #endif /* Did we voluntarily give up some? if so take * one back please */ if ((net->cc_mod.rtcc.vol_reduce) && (inst_ind != SCTP_INST_GAINING)) { net->cwnd += net->mtu; + sctp_enforce_cwnd_limit(&stcb->asoc, net); net->cc_mod.rtcc.vol_reduce--; } net->cc_mod.rtcc.last_step_state = 2; net->cc_mod.rtcc.step_cnt = 0; } goto out_decision; } else if (net->rtt < net->cc_mod.rtcc.lbw_rtt-rtt_offset) { /* bw & rtt decreased */ @@ -491,16 +507,17 @@ cc_bw_decrease(struct sctp_tcb *stcb SCT ((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), oth, probepoint); #endif if ((net->cc_mod.rtcc.vol_reduce) && (inst_ind != SCTP_INST_GAINING)) { net->cwnd += net->mtu; + sctp_enforce_cwnd_limit(&stcb->asoc, net); net->cc_mod.rtcc.vol_reduce--; } net->cc_mod.rtcc.last_step_state = 3; net->cc_mod.rtcc.step_cnt = 0; } goto out_decision; } /* The bw decreased but rtt stayed the same */ @@ -526,16 +543,17 @@ cc_bw_decrease(struct sctp_tcb *stcb SCT ((net->cc_mod.rtcc.lbw << 32) | nbw), ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt), oth, probepoint); #endif if ((net->cc_mod.rtcc.vol_reduce) && (inst_ind != SCTP_INST_GAINING)) { net->cwnd += net->mtu; + sctp_enforce_cwnd_limit(&stcb->asoc, net); net->cc_mod.rtcc.vol_reduce--; } net->cc_mod.rtcc.last_step_state = 4; net->cc_mod.rtcc.step_cnt = 0; } out_decision: net->cc_mod.rtcc.lbw = nbw; net->cc_mod.rtcc.lbw_rtt = net->rtt; @@ -956,16 +974,17 @@ sctp_cwnd_update_after_sack_common(struc default: incr = net->net_ack; if (incr > net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable)) { incr = net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable); } break; } net->cwnd += incr; + sctp_enforce_cwnd_limit(asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, incr, SCTP_CWND_LOG_FROM_SS); } #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE(sctp, cwnd, net, ack, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), @@ -1023,16 +1042,17 @@ sctp_cwnd_update_after_sack_common(struc incr = net->mtu; } break; default: incr = net->mtu; break; } net->cwnd += incr; + sctp_enforce_cwnd_limit(asoc, net); #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE(sctp, cwnd, net, ack, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, old_cwnd, net->cwnd); #endif if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { @@ -1310,17 +1330,17 @@ sctp_cwnd_update_after_packet_dropped(st if (net->cwnd > bw_avail) { /* We can't exceed the pipe size */ net->cwnd = bw_avail; } if (net->cwnd < net->mtu) { /* We always have 1 MTU */ net->cwnd = net->mtu; } - + sctp_enforce_cwnd_limit(&stcb->asoc, net); if (net->cwnd - old_cwnd != 0) { /* log only changes */ #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE(sctp, cwnd, net, pd, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, old_cwnd, net->cwnd); @@ -1337,16 +1357,17 @@ sctp_cwnd_update_after_output(struct sct struct sctp_nets *net, int burst_limit) { int old_cwnd = net->cwnd; if (net->ssthresh < net->cwnd) net->ssthresh = net->cwnd; if (burst_limit) { net->cwnd = (net->flight_size + (burst_limit * net->mtu)); + sctp_enforce_cwnd_limit(&stcb->asoc, net); #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE(sctp, cwnd, net, bl, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, old_cwnd, net->cwnd); #endif if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { @@ -1676,46 +1697,42 @@ struct sctp_hs_raise_drop sctp_cwnd_adju {89053, 72, 10}, /* 71 */ {94717, 73, 9} /* 72 */ }; static void sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net) { int cur_val, i, indx, incr; + int old_cwnd = net->cwnd; cur_val = net->cwnd >> 10; indx = SCTP_HS_TABLE_SIZE - 1; if (cur_val < sctp_cwnd_adjust[0].cwnd) { /* normal mode */ if (net->net_ack > net->mtu) { net->cwnd += net->mtu; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { - sctp_log_cwnd(stcb, net, net->mtu, SCTP_CWND_LOG_FROM_SS); - } } else { net->cwnd += net->net_ack; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { - sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_FROM_SS); - } } } else { for (i = net->last_hs_used; i < SCTP_HS_TABLE_SIZE; i++) { if (cur_val < sctp_cwnd_adjust[i].cwnd) { indx = i; break; } } net->last_hs_used = indx; incr = ((sctp_cwnd_adjust[indx].increase) << 10); net->cwnd += incr; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { - sctp_log_cwnd(stcb, net, incr, SCTP_CWND_LOG_FROM_SS); - } + } + sctp_enforce_cwnd_limit(&stcb->asoc, net); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SS); } } static void sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net) { int cur_val, i, indx; int old_cwnd = net->cwnd; @@ -1744,16 +1761,17 @@ sctp_hs_cwnd_decrease(struct sctp_tcb *s for (i = indx; i >= 1; i--) { if (cur_val > sctp_cwnd_adjust[i - 1].cwnd) { break; } } net->last_hs_used = indx; } } + sctp_enforce_cwnd_limit(&stcb->asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_FR); } } static void sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb, struct sctp_association *asoc) @@ -1872,32 +1890,31 @@ sctp_hs_cwnd_update_after_sack(struct sc * moved. */ if (accum_moved || ((asoc->sctp_cmt_on_off > 0) && net->new_pseudo_cumack)) { /* If the cumulative ack moved we can proceed */ if (net->cwnd <= net->ssthresh) { /* We are in slow start */ if (net->flight_size + net->net_ack >= net->cwnd) { - sctp_hs_cwnd_increase(stcb, net); - } else { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_NOADV_SS); } } } else { /* We are in congestion avoidance */ net->partial_bytes_acked += net->net_ack; if ((net->flight_size + net->net_ack >= net->cwnd) && (net->partial_bytes_acked >= net->cwnd)) { net->partial_bytes_acked -= net->cwnd; net->cwnd += net->mtu; + sctp_enforce_cwnd_limit(asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, net->mtu, SCTP_CWND_LOG_FROM_CA); } } else { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_NOADV_CA); @@ -2126,16 +2143,17 @@ htcp_cong_avoid(struct sctp_tcb *stcb, s } else { net->cwnd += net->net_ack; if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_FROM_SS); } } + sctp_enforce_cwnd_limit(&stcb->asoc, net); } else { if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_NOADV_SS); } } } else { measure_rtt(net); @@ -2146,16 +2164,17 @@ htcp_cong_avoid(struct sctp_tcb *stcb, s /* What is snd_cwnd_cnt?? */ if (((net->partial_bytes_acked/net->mtu * net->cc_mod.htcp_ca.alpha) >> 7)*net->mtu >= net->cwnd) { /*- * Does SCTP have a cwnd clamp? * if (net->snd_cwnd < net->snd_cwnd_clamp) - Nope (RRS). */ net->cwnd += net->mtu; net->partial_bytes_acked = 0; + sctp_enforce_cwnd_limit(&stcb->asoc, net); htcp_alpha_update(&net->cc_mod.htcp_ca); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, net->mtu, SCTP_CWND_LOG_FROM_CA); } } else { net->partial_bytes_acked += net->net_ack; if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { @@ -2191,16 +2210,17 @@ static void sctp_htcp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) { /* * We take the max of the burst limit times a MTU or the * INITIAL_CWND. We then limit this to 4 MTU's of sending. */ net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND)); net->ssthresh = stcb->asoc.peers_rwnd; + sctp_enforce_cwnd_limit(&stcb->asoc, net); htcp_init(net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE|SCTP_CWND_LOGGING_ENABLE)) { sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION); } } static void @@ -2270,17 +2290,17 @@ sctp_htcp_cwnd_update_after_sack(struct } } static void sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb, struct sctp_association *asoc) { struct sctp_nets *net; - /* + /* * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off > 0) && * (net->fast_retran_loss_recovery == 0))) */ TAILQ_FOREACH(net, &asoc->nets, sctp_next) { if ((asoc->fast_retran_loss_recovery == 0) || (asoc->sctp_cmt_on_off > 0)) { /* out of a RFC2582 Fast recovery window? */ if (net->net_ack > 0) { @@ -2292,16 +2312,17 @@ sctp_htcp_cwnd_update_after_fr(struct sc */ struct sctp_tmit_chunk *lchk; int old_cwnd = net->cwnd; /* JRS - reset as if state were changed */ htcp_reset(&net->cc_mod.htcp_ca); net->ssthresh = htcp_recalc_ssthresh(net); net->cwnd = net->ssthresh; + sctp_enforce_cwnd_limit(asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_FR); } lchk = TAILQ_FIRST(&asoc->send_queue); net->partial_bytes_acked = 0; /* Turn on fast recovery window */ @@ -2370,16 +2391,17 @@ sctp_htcp_cwnd_update_after_ecn_echo(str SCTP_STAT_INCR(sctps_ecnereducedcwnd); net->ssthresh = htcp_recalc_ssthresh(net); if (net->ssthresh < net->mtu) { net->ssthresh = net->mtu; /* here back off the timer as well, to slow us down */ net->RTO <<= 1; } net->cwnd = net->ssthresh; + sctp_enforce_cwnd_limit(&stcb->asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); } } } struct sctp_cc_functions sctp_cc_functions[] = { {
--- a/netwerk/sctp/src/netinet/sctp_indata.c +++ b/netwerk/sctp/src/netinet/sctp_indata.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 276914 2015-01-10 20:49:57Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 280440 2015-03-24 15:05:36Z tuexen $"); #endif #include <netinet/sctp_os.h> #include <netinet/sctp_var.h> #include <netinet/sctp_sysctl.h> #include <netinet/sctp_pcb.h> #include <netinet/sctp_header.h> #include <netinet/sctputil.h> @@ -2614,22 +2614,24 @@ sctp_process_segment_range(struct sctp_t /*- * CMT: CUCv2 algorithm. For each TSN being * processed from the sent queue, track the * next expected pseudo-cumack, or * rtx_pseudo_cumack, if required. Separate * cumack trackers for first transmissions, * and retransmissions. */ - if ((tp1->whoTo->find_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) && + if ((tp1->sent < SCTP_DATAGRAM_RESEND) && + (tp1->whoTo->find_pseudo_cumack == 1) && (tp1->snd_count == 1)) { tp1->whoTo->pseudo_cumack = tp1->rec.data.TSN_seq; tp1->whoTo->find_pseudo_cumack = 0; } - if ((tp1->whoTo->find_rtx_pseudo_cumack == 1) && (tp1->sent < SCTP_DATAGRAM_RESEND) && + if ((tp1->sent < SCTP_DATAGRAM_RESEND) && + (tp1->whoTo->find_rtx_pseudo_cumack == 1) && (tp1->snd_count > 1)) { tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.TSN_seq; tp1->whoTo->find_rtx_pseudo_cumack = 0; } if (tp1->rec.data.TSN_seq == theTSN) { if (tp1->sent != SCTP_DATAGRAM_UNSENT) { /*- * must be held until @@ -3515,17 +3517,17 @@ static void sctp_window_probe_recovery(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_tmit_chunk *tp1) { tp1->window_probe = 0; if ((tp1->sent >= SCTP_DATAGRAM_ACKED) || (tp1->data == NULL)) { /* TSN's skipped we do NOT move back. */ sctp_misc_ints(SCTP_FLIGHT_LOG_DWN_WP_FWD, - tp1->whoTo->flight_size, + tp1->whoTo ? tp1->whoTo->flight_size : 0, tp1->book_size, (uintptr_t)tp1->whoTo, tp1->rec.data.TSN_seq); return; } /* First setup this by shrinking flight */ if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) { (*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged)(tp1->whoTo,
--- a/netwerk/sctp/src/netinet/sctp_input.c +++ b/netwerk/sctp/src/netinet/sctp_input.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 277805 2015-01-27 19:35:38Z delphij $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 279859 2015-03-10 19:49:25Z tuexen $"); #endif #include <netinet/sctp_os.h> #include <netinet/sctp_var.h> #include <netinet/sctp_sysctl.h> #include <netinet/sctp_pcb.h> #include <netinet/sctp_header.h> #include <netinet/sctputil.h> @@ -2892,16 +2892,17 @@ sctp_handle_cookie_echo(struct mbuf *m, SCTP_PCB_FLAGS_IN_TCPPOOL | SCTP_PCB_FLAGS_UNBOUND | (SCTP_PCB_COPY_FLAGS & (*inp_p)->sctp_flags) | SCTP_PCB_FLAGS_DONT_WAKE); inp->sctp_features = (*inp_p)->sctp_features; inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features; inp->sctp_socket = so; inp->sctp_frag_point = (*inp_p)->sctp_frag_point; + inp->max_cwnd = (*inp_p)->max_cwnd; inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off; inp->ecn_supported = (*inp_p)->ecn_supported; inp->prsctp_supported = (*inp_p)->prsctp_supported; inp->auth_supported = (*inp_p)->auth_supported; inp->asconf_supported = (*inp_p)->asconf_supported; inp->reconfig_supported = (*inp_p)->reconfig_supported; inp->nrsack_supported = (*inp_p)->nrsack_supported; inp->pktdrop_supported = (*inp_p)->pktdrop_supported;
--- a/netwerk/sctp/src/netinet/sctp_os_userspace.h +++ b/netwerk/sctp/src/netinet/sctp_os_userspace.h @@ -268,17 +268,16 @@ typedef char* caddr_t; #define LITTLE_ENDIAN 0 #ifdef WORDS_BIGENDIAN #define BYTE_ORDER BIG_ENDIAN #else #define BYTE_ORDER LITTLE_ENDIAN #endif #else /* !defined(Userspace_os_Windows) */ -#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */ #include <sys/socket.h> #if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl) #include <pthread.h> #endif typedef pthread_mutex_t userland_mutex_t; typedef pthread_cond_t userland_cond_t; typedef pthread_t userland_thread_t; #endif @@ -432,20 +431,20 @@ struct selinfo {int dummy;}; struct sx {int dummy;}; #endif #include <stdio.h> #include <string.h> /* #include <sys/param.h> in FreeBSD defines MSIZE */ /* #include <sys/ktr.h> */ /* #include <sys/systm.h> */ -#if defined(__Userspace_os_Windows) +#if defined(HAVE_SYS_QUEUE_H) +#include <sys/queue.h> +#else #include <user_queue.h> -#else -#include <sys/queue.h> #endif #include <user_malloc.h> /* #include <sys/kernel.h> */ /* #include <sys/sysctl.h> */ /* #include <sys/protosw.h> */ /* on FreeBSD, this results in a redefintion of SOCK(BUF)_(UN)LOCK and * uknown type of struct mtx for sb_mtx in struct sockbuf */ #include "user_socketvar.h" /* MALLOC_DECLARE's M_PCB. Replacement for sys/socketvar.h */ @@ -491,17 +490,17 @@ struct sx {int dummy;}; #include <user_ip_icmp.h> #endif /* #include <netinet/in_pcb.h> ported to userspace */ #include <user_inpcb.h> /* for getifaddrs */ #include <sys/types.h> #if !defined(__Userspace_os_Windows) -#if !defined(ANDROID) && (defined(INET) || defined(INET6)) +#if defined(INET) || defined(INET6) #include <ifaddrs.h> #endif /* for ioctl */ #include <sys/ioctl.h> /* for close, etc. */ #include <unistd.h>
--- a/netwerk/sctp/src/netinet/sctp_output.c +++ b/netwerk/sctp/src/netinet/sctp_output.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 277350 2015-01-18 22:00:39Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 280371 2015-03-23 15:12:02Z tuexen $"); #endif #include <netinet/sctp_os.h> #ifdef __FreeBSD__ #include <sys/proc.h> #endif #include <netinet/sctp_var.h> #include <netinet/sctp_sysctl.h> @@ -9730,18 +9730,16 @@ sctp_send_asconf_ack(struct sctp_tcb *st chk->rec.chunk_id.id = SCTP_ASCONF_ACK; chk->rec.chunk_id.can_take_data = 1; chk->flags = CHUNK_FLAGS_FRAGMENT_OK; chk->whoTo = net; if (chk->whoTo) { atomic_add_int(&chk->whoTo->ref_count, 1); } chk->data = m_ack; - chk->send_size = 0; - /* Get size */ chk->send_size = ack->len; chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; chk->asoc = &stcb->asoc; TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next); chk->asoc->ctrl_queue_cnt++; }
--- a/netwerk/sctp/src/netinet/sctp_pcb.c +++ b/netwerk/sctp/src/netinet/sctp_pcb.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 277031 2015-01-11 21:55:30Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 280459 2015-03-24 21:12:45Z tuexen $"); #endif #include <netinet/sctp_os.h> #ifdef __FreeBSD__ #include <sys/proc.h> #endif #include <netinet/sctp_var.h> #include <netinet/sctp_sysctl.h> @@ -66,16 +66,19 @@ #endif #if defined(__FreeBSD__) #include <sys/sched.h> #include <sys/smp.h> #include <sys/unistd.h> #endif #if defined(__Userspace__) #include <user_socketvar.h> +#if !defined(__Userspace_os_Windows) +#include <netdb.h> +#endif #endif #if defined(__APPLE__) #define APPLE_FILE_NO 4 #endif #if defined(__FreeBSD__) && __FreeBSD_version >= 801000 VNET_DEFINE(struct sctp_base_info, system_base_info); @@ -2196,30 +2199,31 @@ sctp_isport_inuse(struct sctp_inpcb *inp } int sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp) { /* For 1-2-1 with port reuse */ struct sctppcbhead *head; - struct sctp_inpcb *tinp; + struct sctp_inpcb *tinp, *ninp; if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE)) { /* only works with port reuse on */ return (-1); } if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) { return (0); } SCTP_INP_RUNLOCK(inp); + SCTP_INP_INFO_WLOCK(); head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport, SCTP_BASE_INFO(hashmark))]; /* Kick out all non-listeners to the TCP hash */ - LIST_FOREACH(tinp, head, sctp_hash) { + LIST_FOREACH_SAFE(tinp, head, sctp_hash, ninp) { if (tinp->sctp_lport != inp->sctp_lport) { continue; } if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { continue; } if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { continue; @@ -2237,16 +2241,17 @@ sctp_swap_inpcb_for_listen(struct sctp_i SCTP_INP_WLOCK(inp); /* Pull from where he was */ LIST_REMOVE(inp, sctp_hash); inp->sctp_flags &= ~SCTP_PCB_FLAGS_IN_TCPPOOL; head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport, SCTP_BASE_INFO(hashmark))]; LIST_INSERT_HEAD(head, inp, sctp_hash); SCTP_INP_WUNLOCK(inp); SCTP_INP_RLOCK(inp); + SCTP_INP_INFO_WUNLOCK(); return (0); } struct sctp_inpcb * sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock, uint32_t vrf_id) { @@ -2827,16 +2832,17 @@ sctp_inpcb_alloc(struct socket *so, uint inp->ip_inp.inp.inp_flags |= IN6P_IPV6_V6ONLY; } } #endif #endif inp->sctp_associd_counter = 1; inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT; inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; + inp->max_cwnd = 0; inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off); inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable); inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable); inp->auth_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_auth_enable); inp->asconf_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_asconf_enable); inp->reconfig_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_reconfig_enable); inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable); inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
--- a/netwerk/sctp/src/netinet/sctp_pcb.h +++ b/netwerk/sctp/src/netinet/sctp_pcb.h @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 275427 2014-12-02 20:29:29Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 279859 2015-03-10 19:49:25Z tuexen $"); #endif #ifndef _NETINET_SCTP_PCB_H_ #define _NETINET_SCTP_PCB_H_ #include <netinet/sctp_os.h> #include <netinet/sctp.h> #include <netinet/sctp_constants.h> @@ -473,16 +473,17 @@ struct sctp_inpcb { struct sctpasochead sctp_asoc_list; #ifdef SCTP_TRACK_FREED_ASOCS struct sctpasochead sctp_asoc_free_list; #endif struct sctp_iterator *inp_starting_point_for_iterator; uint32_t sctp_frag_point; uint32_t partial_delivery_point; uint32_t sctp_context; + uint32_t max_cwnd; uint8_t local_strreset_support; uint32_t sctp_cmt_on_off; uint8_t ecn_supported; uint8_t prsctp_supported; uint8_t auth_supported; uint8_t asconf_supported; uint8_t reconfig_supported; uint8_t nrsack_supported;
--- a/netwerk/sctp/src/netinet/sctp_peeloff.c +++ b/netwerk/sctp/src/netinet/sctp_peeloff.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 269858 2014-08-12 11:30:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 279859 2015-03-10 19:49:25Z tuexen $"); #endif #include <netinet/sctp_os.h> #include <netinet/sctp_pcb.h> #include <netinet/sctputil.h> #include <netinet/sctp_var.h> #include <netinet/sctp_var.h> #include <netinet/sctp_sysctl.h> @@ -129,16 +129,17 @@ sctp_do_peeloff(struct socket *head, str n_inp->prsctp_supported = inp->prsctp_supported; n_inp->auth_supported = inp->auth_supported; n_inp->asconf_supported = inp->asconf_supported; n_inp->reconfig_supported = inp->reconfig_supported; n_inp->nrsack_supported = inp->nrsack_supported; n_inp->pktdrop_supported = inp->pktdrop_supported; n_inp->partial_delivery_point = inp->partial_delivery_point; n_inp->sctp_context = inp->sctp_context; + n_inp->max_cwnd = inp->max_cwnd; n_inp->local_strreset_support = inp->local_strreset_support; n_inp->inp_starting_point_for_iterator = NULL; /* copy in the authentication parameters from the original endpoint */ if (n_inp->sctp_ep.local_hmacs) sctp_free_hmaclist(n_inp->sctp_ep.local_hmacs); n_inp->sctp_ep.local_hmacs = sctp_copy_hmaclist(inp->sctp_ep.local_hmacs); if (n_inp->sctp_ep.local_auth_chunks) @@ -244,16 +245,17 @@ sctp_get_peeloff(struct socket *head, sc n_inp->prsctp_supported = inp->prsctp_supported; n_inp->auth_supported = inp->auth_supported; n_inp->asconf_supported = inp->asconf_supported; n_inp->reconfig_supported = inp->reconfig_supported; n_inp->nrsack_supported = inp->nrsack_supported; n_inp->pktdrop_supported = inp->pktdrop_supported; n_inp->partial_delivery_point = inp->partial_delivery_point; n_inp->sctp_context = inp->sctp_context; + n_inp->max_cwnd = inp->max_cwnd; n_inp->local_strreset_support = inp->local_strreset_support; n_inp->inp_starting_point_for_iterator = NULL; #if defined(__Userspace__) n_inp->ulp_info = inp->ulp_info; n_inp->recv_callback = inp->recv_callback; n_inp->send_callback = inp->send_callback; n_inp->send_sb_threshold = inp->send_sb_threshold; #endif
--- a/netwerk/sctp/src/netinet/sctp_structs.h +++ b/netwerk/sctp/src/netinet/sctp_structs.h @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 275483 2014-12-04 21:17:50Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 279859 2015-03-10 19:49:25Z tuexen $"); #endif #ifndef _NETINET_SCTP_STRUCTS_H_ #define _NETINET_SCTP_STRUCTS_H_ #include <netinet/sctp_os.h> #include <netinet/sctp_header.h> #include <netinet/sctp_auth.h> @@ -1244,16 +1244,17 @@ struct sctp_association { uint8_t cmt_dac_pkts_rcvd; uint8_t sctp_cmt_on_off; uint8_t iam_blocking; uint8_t cookie_how[8]; /* JRS 5/21/07 - CMT PF variable */ uint8_t sctp_cmt_pf; uint8_t use_precise_time; uint64_t sctp_features; + uint32_t max_cwnd; uint16_t port; /* remote UDP encapsulation port */ /* * The mapping array is used to track out of order sequences above * last_acked_seq. 0 indicates packet missing 1 indicates packet * rec'd. We slide it up every time we raise last_acked_seq and 0 * trailing locactions out. If I get a TSN above the array * mappingArraySz, I discard the datagram and let retransmit happen. */
--- a/netwerk/sctp/src/netinet/sctp_timer.c +++ b/netwerk/sctp/src/netinet/sctp_timer.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 277380 2015-01-19 11:52:08Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 279841 2015-03-10 09:16:31Z tuexen $"); #endif #define _IP_VHL #include <netinet/sctp_os.h> #include <netinet/sctp_pcb.h> #ifdef INET6 #if defined(__Userspace_os_FreeBSD) #include <netinet6/sctp6_var.h> @@ -157,17 +157,17 @@ sctp_threshold_management(struct sctp_in * We specifically do not do >= to give the assoc one more change * before we fail it. */ if (stcb->asoc.overall_error_count > threshold) { /* Abort notification sends a ULP notify */ struct mbuf *op_err; op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, - "Association error couter exceeded"); + "Association error counter exceeded"); inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_1; sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); return (1); } return (0); } /*
--- a/netwerk/sctp/src/netinet/sctp_usrreq.c +++ b/netwerk/sctp/src/netinet/sctp_usrreq.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 277815 2015-01-27 21:30:24Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 280459 2015-03-24 21:12:45Z tuexen $"); #endif #include <netinet/sctp_os.h> #ifdef __FreeBSD__ #include <sys/proc.h> #endif #include <netinet/sctp_pcb.h> #include <netinet/sctp_header.h> @@ -290,31 +290,29 @@ sctp_pathmtu_adjustment(struct sctp_tcb /* * For this guy we also mark for immediate resend * since we sent to big of chunk */ chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; if (chk->sent < SCTP_DATAGRAM_RESEND) { sctp_flight_size_decrease(chk); sctp_total_flight_decrease(stcb, chk); - } - if (chk->sent != SCTP_DATAGRAM_RESEND) { + chk->sent = SCTP_DATAGRAM_RESEND; sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); - } - chk->sent = SCTP_DATAGRAM_RESEND; - chk->rec.data.doing_fast_retransmit = 0; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) { - sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU, - chk->whoTo->flight_size, - chk->book_size, - (uintptr_t)chk->whoTo, - chk->rec.data.TSN_seq); - } - /* Clear any time so NO RTT is being done */ - chk->do_rtt = 0; + chk->rec.data.doing_fast_retransmit = 0; + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) { + sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU, + chk->whoTo->flight_size, + chk->book_size, + (uintptr_t)chk->whoTo, + chk->rec.data.TSN_seq); + } + /* Clear any time so NO RTT is being done */ + chk->do_rtt = 0; + } } } } #ifdef INET #if !defined(__Userspace__) #if defined(__Panda__) || defined(__Windows__) void @@ -4383,16 +4381,43 @@ sctp_getopt(struct socket *so, int optna SCTP_TCB_UNLOCK(stcb); *optsize = sizeof(struct sctp_prstatus); } else { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; } break; } + case SCTP_MAX_CWND: + { + struct sctp_assoc_value *av; + + SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); + SCTP_FIND_STCB(inp, stcb, av->assoc_id); + + if (stcb) { + av->assoc_value = stcb->asoc.max_cwnd; + SCTP_TCB_UNLOCK(stcb); + } else { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || + (av->assoc_id == SCTP_FUTURE_ASSOC)) { + SCTP_INP_RLOCK(inp); + av->assoc_value = inp->max_cwnd; + SCTP_INP_RUNLOCK(inp); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + } + if (error == 0) { + *optsize = sizeof(struct sctp_assoc_value); + } + break; + } default: SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); error = ENOPROTOOPT; break; } /* end switch (sopt->sopt_name) */ if (error) { *optsize = 0; } @@ -7032,76 +7057,77 @@ sctp_setopt(struct socket *so, int optna error = EAFNOSUPPORT; SCTP_TCB_UNLOCK(stcb); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); break; } } if (stcb != NULL) { if (net != NULL) { + net->failure_threshold = thlds->spt_pathmaxrxt; + net->pf_threshold = thlds->spt_pathpfthld; if (net->dest_state & SCTP_ADDR_PF) { - if ((net->failure_threshold > thlds->spt_pathmaxrxt) || - (net->failure_threshold <= thlds->spt_pathpfthld)) { + if ((net->error_count > net->failure_threshold) || + (net->error_count <= net->pf_threshold)) { net->dest_state &= ~SCTP_ADDR_PF; } } else { - if ((net->failure_threshold > thlds->spt_pathpfthld) && - (net->failure_threshold <= thlds->spt_pathmaxrxt)) { + if ((net->error_count > net->pf_threshold) && + (net->error_count <= net->failure_threshold)) { net->dest_state |= SCTP_ADDR_PF; sctp_send_hb(stcb, net, SCTP_SO_LOCKED); sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); } } if (net->dest_state & SCTP_ADDR_REACHABLE) { - if (net->failure_threshold > thlds->spt_pathmaxrxt) { + if (net->error_count > net->failure_threshold) { net->dest_state &= ~SCTP_ADDR_REACHABLE; sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); } } else { - if (net->failure_threshold <= thlds->spt_pathmaxrxt) { + if (net->error_count <= net->failure_threshold) { net->dest_state |= SCTP_ADDR_REACHABLE; sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); } } - net->failure_threshold = thlds->spt_pathmaxrxt; - net->pf_threshold = thlds->spt_pathpfthld; } else { TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { + net->failure_threshold = thlds->spt_pathmaxrxt; + net->pf_threshold = thlds->spt_pathpfthld; if (net->dest_state & SCTP_ADDR_PF) { - if ((net->failure_threshold > thlds->spt_pathmaxrxt) || - (net->failure_threshold <= thlds->spt_pathpfthld)) { + if ((net->error_count > net->failure_threshold) || + (net->error_count <= net->pf_threshold)) { net->dest_state &= ~SCTP_ADDR_PF; } } else { - if ((net->failure_threshold > thlds->spt_pathpfthld) && - (net->failure_threshold <= thlds->spt_pathmaxrxt)) { + if ((net->error_count > net->pf_threshold) && + (net->error_count <= net->failure_threshold)) { net->dest_state |= SCTP_ADDR_PF; sctp_send_hb(stcb, net, SCTP_SO_LOCKED); sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); } } if (net->dest_state & SCTP_ADDR_REACHABLE) { - if (net->failure_threshold > thlds->spt_pathmaxrxt) { + if (net->error_count > net->failure_threshold) { net->dest_state &= ~SCTP_ADDR_REACHABLE; sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); } } else { - if (net->failure_threshold <= thlds->spt_pathmaxrxt) { + if (net->error_count <= net->failure_threshold) { net->dest_state |= SCTP_ADDR_REACHABLE; sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); } } - net->failure_threshold = thlds->spt_pathmaxrxt; - net->pf_threshold = thlds->spt_pathpfthld; } stcb->asoc.def_net_failure = thlds->spt_pathmaxrxt; stcb->asoc.def_net_pf_threshold = thlds->spt_pathpfthld; } + SCTP_TCB_UNLOCK(stcb); } else { if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC)) { SCTP_INP_WLOCK(inp); inp->sctp_ep.def_net_failure = thlds->spt_pathmaxrxt; inp->sctp_ep.def_net_pf_threshold = thlds->spt_pathpfthld; SCTP_INP_WUNLOCK(inp); @@ -7444,16 +7470,52 @@ sctp_setopt(struct socket *so, int optna SCTP_INP_WUNLOCK(inp); } else { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; } } break; } + case SCTP_MAX_CWND: + { + struct sctp_assoc_value *av; + struct sctp_nets *net; + + SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); + SCTP_FIND_STCB(inp, stcb, av->assoc_id); + + if (stcb) { + stcb->asoc.max_cwnd = av->assoc_value; + if (stcb->asoc.max_cwnd > 0) { + TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { + if ((net->cwnd > stcb->asoc.max_cwnd) && + (net->cwnd > (net->mtu - sizeof(struct sctphdr)))) { + net->cwnd = stcb->asoc.max_cwnd; + if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) { + net->cwnd = net->mtu - sizeof(struct sctphdr); + } + } + } + } + SCTP_TCB_UNLOCK(stcb); + } else { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || + (av->assoc_id == SCTP_FUTURE_ASSOC)) { + SCTP_INP_WLOCK(inp); + inp->max_cwnd = av->assoc_value; + SCTP_INP_WUNLOCK(inp); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + } + break; + } default: SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); error = ENOPROTOOPT; break; } /* end switch (opt) */ return (error); } @@ -8042,54 +8104,53 @@ sctp_listen(struct socket *so, struct pr #ifdef SCTP_LOCK_LOGGING if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) { sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK); } #endif SOCK_LOCK(so); #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Userspace__) error = solisten_proto_check(so); + SOCK_UNLOCK(so); if (error) { - SOCK_UNLOCK(so); SCTP_INP_RUNLOCK(inp); return (error); } #endif if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) && (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { /* The unlucky case * - We are in the tcp pool with this guy. * - Someone else is in the main inp slot. * - We must move this guy (the listener) to the main slot * - We must then move the guy that was listener to the TCP Pool. */ if (sctp_swap_inpcb_for_listen(inp)) { - goto in_use; + SCTP_INP_RUNLOCK(inp); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); + return (EADDRINUSE); } } if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { /* We are already connected AND the TCP model */ - in_use: SCTP_INP_RUNLOCK(inp); - SOCK_UNLOCK(so); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); return (EADDRINUSE); } SCTP_INP_RUNLOCK(inp); if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { /* We must do a bind. */ - SOCK_UNLOCK(so); if ((error = sctp_inpcb_bind(so, NULL, NULL, p))) { /* bind error, probably perm */ return (error); } - SOCK_LOCK(so); - } + } + SOCK_LOCK(so); #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__) || defined(__Userspace__) #if __FreeBSD_version >= 700000 || defined(__Windows__) || defined(__Userspace__) /* It appears for 7.0 and on, we must always call this. */ solisten_proto(so, backlog); #else if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) == 0) { solisten_proto(so); }
--- a/netwerk/sctp/src/netinet/sctputil.c +++ b/netwerk/sctp/src/netinet/sctputil.c @@ -27,17 +27,17 @@ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 277049 2015-01-12 07:39:52Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 280439 2015-03-24 14:51:46Z tuexen $"); #endif #include <netinet/sctp_os.h> #include <netinet/sctp_pcb.h> #include <netinet/sctputil.h> #include <netinet/sctp_var.h> #include <netinet/sctp_sysctl.h> #ifdef INET6 @@ -995,16 +995,17 @@ sctp_init_asoc(struct sctp_inpcb *inp, s asoc->asconf_supported = inp->asconf_supported; asoc->reconfig_supported = inp->reconfig_supported; asoc->nrsack_supported = inp->nrsack_supported; asoc->pktdrop_supported = inp->pktdrop_supported; asoc->sctp_cmt_pf = (uint8_t)0; asoc->sctp_frag_point = inp->sctp_frag_point; asoc->sctp_features = inp->sctp_features; asoc->default_dscp = inp->sctp_ep.default_dscp; + asoc->max_cwnd = inp->max_cwnd; #ifdef INET6 if (inp->sctp_ep.default_flowlabel) { asoc->default_flowlabel = inp->sctp_ep.default_flowlabel; } else { if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) { asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep); asoc->default_flowlabel &= 0x000fffff; asoc->default_flowlabel |= 0x80000000; @@ -2858,17 +2859,21 @@ set_error: if (!so_locked) { SCTP_SOCKET_UNLOCK(so, 1); } #endif } static void sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state, - struct sockaddr *sa, uint32_t error) + struct sockaddr *sa, uint32_t error, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { struct mbuf *m_notify; struct sctp_paddr_change *spc; struct sctp_queued_to_read *control; if ((stcb == NULL) || sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) { /* event not enabled */ @@ -2954,17 +2959,17 @@ sctp_notify_peer_addr_change(struct sctp control->length = SCTP_BUF_LEN(m_notify); control->spec_flags = M_NOTIFICATION; /* not that we need this */ control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, - SCTP_SO_NOT_LOCKED); + so_locked); } static void sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, struct sctp_tmit_chunk *chk, int so_locked #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) SCTP_UNUSED @@ -3752,35 +3757,35 @@ sctp_ulp_notify(uint32_t notification, s #endif break; case SCTP_NOTIFY_INTERFACE_DOWN: { struct sctp_nets *net; net = (struct sctp_nets *)data; sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE, - (struct sockaddr *)&net->ro._l_addr, error); + (struct sockaddr *)&net->ro._l_addr, error, so_locked); break; } case SCTP_NOTIFY_INTERFACE_UP: { struct sctp_nets *net; net = (struct sctp_nets *)data; sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE, - (struct sockaddr *)&net->ro._l_addr, error); + (struct sockaddr *)&net->ro._l_addr, error, so_locked); break; } case SCTP_NOTIFY_INTERFACE_CONFIRMED: { struct sctp_nets *net; net = (struct sctp_nets *)data; sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED, - (struct sockaddr *)&net->ro._l_addr, error); + (struct sockaddr *)&net->ro._l_addr, error, so_locked); break; } case SCTP_NOTIFY_SPECIAL_SP_FAIL: sctp_notify_send_failed2(stcb, error, (struct sctp_stream_queue_pending *)data, so_locked); break; case SCTP_NOTIFY_SENT_DG_FAIL: sctp_notify_send_failed(stcb, 1, error, @@ -3840,25 +3845,25 @@ sctp_ulp_notify(uint32_t notification, s (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED)); break; case SCTP_NOTIFY_STR_RESET_DENIED_IN: sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_DENIED)); break; case SCTP_NOTIFY_ASCONF_ADD_IP: sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data, - error); + error, so_locked); break; case SCTP_NOTIFY_ASCONF_DELETE_IP: sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data, - error); + error, so_locked); break; case SCTP_NOTIFY_ASCONF_SET_PRIMARY: sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data, - error); + error, so_locked); break; case SCTP_NOTIFY_PEER_SHUTDOWN: sctp_notify_shutdown_event(stcb); break; case SCTP_NOTIFY_AUTH_NEW_KEY: sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error, (uint16_t)(uintptr_t)data, so_locked); @@ -5332,27 +5337,23 @@ sctp_release_pr_sctp_chunk(struct sctp_t chk->rec.data.rcv_flags = SCTP_DATA_LAST_FRAG; chk->sent = SCTP_FORWARD_TSN_SKIP; chk->asoc = &stcb->asoc; chk->rec.data.stream_seq = strq->next_sequence_send; chk->rec.data.stream_number = sp->stream; chk->rec.data.payloadtype = sp->ppid; chk->rec.data.context = sp->context; chk->flags = sp->act_flags; - if (sp->net) - chk->whoTo = sp->net; - else - chk->whoTo = stcb->asoc.primary_destination; - atomic_add_int(&chk->whoTo->ref_count, 1); + chk->whoTo = NULL; #if defined(__FreeBSD__) || defined(__Panda__) chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1); #else chk->rec.data.TSN_seq = stcb->asoc.sending_seq++; #endif - stcb->asoc.pr_sctp_cnt++; + strq->chunks_on_queues++; TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next); stcb->asoc.sent_queue_cnt++; stcb->asoc.pr_sctp_cnt++; } else { chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG; } strq->next_sequence_send++; oh_well:
--- a/netwerk/sctp/src/user_queue.h +++ b/netwerk/sctp/src/user_queue.h @@ -26,19 +26,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #ifndef _USER_QUEUE_H_ #define _USER_QUEUE_H_ -#if !defined (__Userspace_os_Windows) -#include <sys/cdefs.h> -#endif /* * This file defines four types of data structures: singly-linked lists, * singly-linked tail queues, lists and tail queues. * * A singly-linked list is headed by a single forward pointer. The elements * are singly linked for minimum space and pointer manipulation overhead at * the expense of O(n) removal for arbitrary elements. New elements can be * added to the list after an existing element or at the head of the list.