diff --git a/build-85.patch b/build-85.patch new file mode 100644 index 0000000..2e8295b --- /dev/null +++ b/build-85.patch @@ -0,0 +1,53 @@ +diff --git a/config/BUILD.gn b/config/BUILD.gn +index d0517299b..3b01e08f3 100644 +--- a/config/BUILD.gn ++++ b/config/BUILD.gn +@@ -119,7 +119,7 @@ config("feature_flags") { + + config("debug") { + defines = [ +- "_DEBUG", ++ "NDEBUG", + "DYNAMIC_ANNOTATIONS_ENABLED=1", + ] + +@@ -131,7 +131,7 @@ config("debug") { + if (!enable_iterator_debugging && !use_custom_libcxx) { + # Iterator debugging is enabled by default by the compiler on debug + # builds, and we have to tell it to turn it off. +- defines += [ "_HAS_ITERATOR_DEBUGGING=0" ] ++ defines += [ "_HAS_ITERATOR_DEBUGGING=1" ] + } + } else if (is_linux && current_cpu == "x64" && enable_iterator_debugging) { + # Enable libstdc++ debugging facilities to help catch problems early, see +diff --git a/config/win/BUILD.gn b/config/win/BUILD.gn +index bd5f8a8ed..dec50a601 100644 +--- a/config/win/BUILD.gn ++++ b/config/win/BUILD.gn +@@ -470,9 +470,9 @@ config("default_crt") { + # defining _DEBUG. + config("release_crt") { + if (is_component_build) { +- cflags = [ "/MD" ] ++ cflags = [ "/MDd" ] + } else { +- cflags = [ "/MT" ] ++ cflags = [ "/MD" ] + } + } + +@@ -488,9 +488,9 @@ config("dynamic_crt") { + config("static_crt") { + if (is_debug) { + # This pulls in the static debug CRT and defines _DEBUG +- cflags = [ "/MTd" ] ++ cflags = [ "/MDd" ] + } else { +- cflags = [ "/MT" ] ++ cflags = [ "/MD" ] + } + } + +-- +2.22.0.windows.1 + diff --git a/build.patch b/build.patch index 2e8295b..df4f8da 100644 --- a/build.patch +++ b/build.patch @@ -1,18 +1,18 @@ diff --git a/config/BUILD.gn b/config/BUILD.gn -index d0517299b..3b01e08f3 100644 +index 10f2fc8ad..e69cdf13c 100644 --- a/config/BUILD.gn +++ b/config/BUILD.gn -@@ -119,7 +119,7 @@ config("feature_flags") { +@@ -155,7 +155,7 @@ config("feature_flags") { config("debug") { defines = [ - "_DEBUG", + "NDEBUG", "DYNAMIC_ANNOTATIONS_ENABLED=1", + "WTF_USE_DYNAMIC_ANNOTATIONS=1", ] - -@@ -131,7 +131,7 @@ config("debug") { - if (!enable_iterator_debugging && !use_custom_libcxx) { +@@ -168,7 +168,7 @@ config("debug") { + if (!enable_iterator_debugging) { # Iterator debugging is enabled by default by the compiler on debug # builds, and we have to tell it to turn it off. - defines += [ "_HAS_ITERATOR_DEBUGGING=0" ] @@ -21,11 +21,11 @@ index d0517299b..3b01e08f3 100644 } else if (is_linux && current_cpu == "x64" && enable_iterator_debugging) { # Enable libstdc++ debugging facilities to help catch problems early, see diff --git a/config/win/BUILD.gn b/config/win/BUILD.gn -index bd5f8a8ed..dec50a601 100644 +index f27f192e3..42db46918 100644 --- a/config/win/BUILD.gn +++ b/config/win/BUILD.gn -@@ -470,9 +470,9 @@ config("default_crt") { - # defining _DEBUG. +@@ -449,9 +449,9 @@ config("default_crt") { + # _DEBUG. config("release_crt") { if (is_component_build) { - cflags = [ "/MD" ] @@ -36,7 +36,7 @@ index bd5f8a8ed..dec50a601 100644 } } -@@ -488,9 +488,9 @@ config("dynamic_crt") { +@@ -467,9 +467,9 @@ config("dynamic_crt") { config("static_crt") { if (is_debug) { # This pulls in the static debug CRT and defines _DEBUG @@ -48,6 +48,3 @@ index bd5f8a8ed..dec50a601 100644 } } --- -2.22.0.windows.1 - diff --git a/usrsctplib-85.patch b/usrsctplib-85.patch new file mode 100644 index 0000000..7eb195c --- /dev/null +++ b/usrsctplib-85.patch @@ -0,0 +1,481 @@ +diff --git a/usrsctplib/netinet/sctp_cc_functions.c b/usrsctplib/netinet/sctp_cc_functions.c +index 0139057..5772134 100755 +--- a/usrsctplib/netinet/sctp_cc_functions.c ++++ b/usrsctplib/netinet/sctp_cc_functions.c +@@ -64,10 +64,7 @@ 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); +- } ++ net->cwnd = SCTP_CWND_SIZE ; + } + } + +@@ -79,26 +76,12 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) + + assoc = &stcb->asoc; + cwnd_in_mtu = SCTP_BASE_SYSCTL(sctp_initial_cwnd); +- if (cwnd_in_mtu == 0) { +- /* Using 0 means that the value of RFC 4960 is used. */ +- net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND)); +- } else { +- /* +- * We take the minimum of the burst limit and the +- * initial congestion window. +- */ +- if ((assoc->max_burst > 0) && (cwnd_in_mtu > assoc->max_burst)) +- cwnd_in_mtu = assoc->max_burst; +- net->cwnd = (net->mtu - sizeof(struct sctphdr)) * cwnd_in_mtu; +- } +- 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); +- } +- } ++ ++ if ((cwnd_in_mtu != 0) && (assoc->max_burst > 0) && (cwnd_in_mtu > assoc->max_burst)) ++ cwnd_in_mtu = assoc->max_burst; ++ ++ net->cwnd = SCTP_CWND_SIZE; ++ + sctp_enforce_cwnd_limit(assoc, net); + net->ssthresh = assoc->peers_rwnd; + #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 +@@ -194,7 +177,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb, + net->ssthresh = 2 * net->mtu; + } + } +- net->cwnd = net->ssthresh; ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(asoc, net); + #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 + SDT_PROBE5(sctp, cwnd, net, fr, +@@ -309,7 +292,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb + probepoint); + #endif + if (net->cwnd > (4 * net->mtu)) { +- net->cwnd -= net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + net->cc_mod.rtcc.vol_reduce++; + } else { + net->cc_mod.rtcc.step_cnt = 0; +@@ -391,7 +374,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb + ((net->cc_mod.rtcc.step_cnt % net->cc_mod.rtcc.steady_step) == 0))) { + /* Try a step down */ + if (net->cwnd > (4 * net->mtu)) { +- net->cwnd -= net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + net->cc_mod.rtcc.vol_reduce++; + return (1); + } else { +@@ -478,7 +461,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ + */ + if ((net->cc_mod.rtcc.vol_reduce) && + (inst_ind != SCTP_INST_GAINING)) { +- net->cwnd += net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(&stcb->asoc, net); + net->cc_mod.rtcc.vol_reduce--; + } +@@ -514,7 +497,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ + #endif + if ((net->cc_mod.rtcc.vol_reduce) && + (inst_ind != SCTP_INST_GAINING)) { +- net->cwnd += net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(&stcb->asoc, net); + net->cc_mod.rtcc.vol_reduce--; + } +@@ -550,7 +533,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ + #endif + if ((net->cc_mod.rtcc.vol_reduce) && + (inst_ind != SCTP_INST_GAINING)) { +- net->cwnd += net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(&stcb->asoc, net); + net->cc_mod.rtcc.vol_reduce--; + } +@@ -981,7 +964,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb, + } + break; + } +- net->cwnd += incr; ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(asoc, net); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, incr, +@@ -1049,7 +1032,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb, + incr = net->mtu; + break; + } +- net->cwnd += incr; ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(asoc, net); + #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 + SDT_PROBE5(sctp, cwnd, net, ack, +@@ -1091,7 +1074,7 @@ sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_n + + old_cwnd = net->cwnd; + #endif +- net->cwnd = net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 + SDT_PROBE5(sctp, cwnd, net, ack, + stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, +@@ -1163,7 +1146,7 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net) + } else { + net->ssthresh = max(net->cwnd / 2, 4 * net->mtu); + } +- net->cwnd = net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + net->partial_bytes_acked = 0; + #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 + SDT_PROBE5(sctp, cwnd, net, to, +@@ -1187,14 +1170,8 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * + if (in_window == 0) { + /* Go to CA with the cwnd at the point we sent + * the TSN that was marked with a CE. +- */ +- if (net->ecn_prev_cwnd < net->cwnd) { +- /* Restore to prev cwnd */ +- net->cwnd = net->ecn_prev_cwnd - (net->mtu * num_pkt_lost); +- } else { +- /* Just cut in 1/2 */ +- net->cwnd /= 2; +- } ++ */ ++ net->cwnd = SCTP_CWND_SIZE; + /* Drop to CA */ + net->ssthresh = net->cwnd - (num_pkt_lost * net->mtu); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { +@@ -1203,7 +1180,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * + } else { + /* Further tuning down required over the drastic original cut */ + net->ssthresh -= (net->mtu * num_pkt_lost); +- net->cwnd -= (net->mtu * num_pkt_lost); ++ net->cwnd = SCTP_CWND_SIZE; + 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); + } +@@ -1219,7 +1196,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * + /* here back off the timer as well, to slow us down */ + net->RTO <<= 1; + } +- net->cwnd = net->ssthresh; ++ net->cwnd = SCTP_CWND_SIZE; + #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 + SDT_PROBE5(sctp, cwnd, net, ecn, + stcb->asoc.my_vtag, +@@ -1283,7 +1260,7 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, + * undo any cwnd adjustment that the sack + * might have made + */ +- net->cwnd = net->prev_cwnd; ++ net->cwnd = SCTP_CWND_SIZE; + } + /* Now how much of that is mine? */ + seg_inflight = net->flight_size / net->mtu; +@@ -1310,12 +1287,8 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, + * had a sack before this packet). minus what ever + * portion of the overage is my fault. + */ +- net->cwnd -= my_portion; ++ net->cwnd = SCTP_CWND_SIZE; + +- /* we will NOT back down more than 1 MTU */ +- if (net->cwnd <= net->mtu) { +- net->cwnd = net->mtu; +- } + /* force into CA */ + net->ssthresh = net->cwnd - 1; + } else { +@@ -1328,16 +1301,11 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, + (stcb->asoc.max_burst * net->mtu < incr)) { + incr = stcb->asoc.max_burst * net->mtu; + } +- net->cwnd += incr; +- } +- 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; ++ net->cwnd = SCTP_CWND_SIZE; + } ++ ++ net->cwnd = SCTP_CWND_SIZE; ++ + sctp_enforce_cwnd_limit(&stcb->asoc, net); + if (net->cwnd - old_cwnd != 0) { + /* log only changes */ +@@ -1364,7 +1332,7 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb, + if (net->ssthresh < net->cwnd) + net->ssthresh = net->cwnd; + if (burst_limit) { +- net->cwnd = (net->flight_size + (burst_limit * net->mtu)); ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(&stcb->asoc, net); + #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 + SDT_PROBE5(sctp, cwnd, net, bl, +@@ -1484,7 +1452,7 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb, + } + if (net->cwnd > cwnd) { + /* Only set if we are not a timeout (i.e. down to 1 mtu) */ +- net->cwnd = cwnd; ++ net->cwnd = SCTP_CWND_SIZE; + } + } + } +@@ -1712,11 +1680,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net) + + if (cur_val < sctp_cwnd_adjust[0].cwnd) { + /* normal mode */ +- if (net->net_ack > net->mtu) { +- net->cwnd += net->mtu; +- } else { +- net->cwnd += net->net_ack; +- } ++ net->cwnd = SCTP_CWND_SIZE; + } else { + for (i = net->last_hs_used; i < SCTP_HS_TABLE_SIZE; i++) { + if (cur_val < sctp_cwnd_adjust[i].cwnd) { +@@ -1726,7 +1690,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net) + } + net->last_hs_used = indx; + incr = (((int32_t)sctp_cwnd_adjust[indx].increase) << 10); +- net->cwnd += incr; ++ net->cwnd = SCTP_CWND_SIZE; + } + sctp_enforce_cwnd_limit(&stcb->asoc, net); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { +@@ -1747,12 +1711,12 @@ sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net) + if (net->ssthresh < (net->mtu * 2)) { + net->ssthresh = 2 * net->mtu; + } +- net->cwnd = net->ssthresh; ++ net->cwnd = SCTP_CWND_SIZE; + } else { + /* drop by the proper amount */ + net->ssthresh = net->cwnd - (int)((net->cwnd / 100) * + (int32_t)sctp_cwnd_adjust[net->last_hs_used].drop_percent); +- net->cwnd = net->ssthresh; ++ net->cwnd = SCTP_CWND_SIZE; + /* now where are we */ + indx = net->last_hs_used; + cur_val = net->cwnd >> 10; +@@ -1912,7 +1876,7 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb, + 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; ++ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(asoc, net); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, net->mtu, +@@ -2138,14 +2102,14 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net) + /* We are in slow start */ + if (net->flight_size + net->net_ack >= net->cwnd) { + if (net->net_ack > (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) { +- net->cwnd += (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable)); ++ net->cwnd = SCTP_CWND_SIZE; + 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; ++ net->cwnd = SCTP_CWND_SIZE; + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, net->net_ack, + SCTP_CWND_LOG_FROM_SS); +@@ -2171,7 +2135,7 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net) + * Does SCTP have a cwnd clamp? + * if (net->snd_cwnd < net->snd_cwnd_clamp) - Nope (RRS). + */ +- net->cwnd += net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + net->partial_bytes_acked = 0; + sctp_enforce_cwnd_limit(&stcb->asoc, net); + htcp_alpha_update(&net->cc_mod.htcp_ca); +@@ -2217,7 +2181,7 @@ 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->cwnd = SCTP_CWND_SIZE; + net->ssthresh = stcb->asoc.peers_rwnd; + sctp_enforce_cwnd_limit(&stcb->asoc, net); + htcp_init(net); +@@ -2320,7 +2284,7 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb, + /* JRS - reset as if state were changed */ + htcp_reset(&net->cc_mod.htcp_ca); + net->ssthresh = htcp_recalc_ssthresh(net); +- net->cwnd = net->ssthresh; ++ net->cwnd = SCTP_CWND_SIZE; + 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), +@@ -2376,7 +2340,7 @@ sctp_htcp_cwnd_update_after_timeout(struct sctp_tcb *stcb, + /* JRS - reset as if the state were being changed to timeout */ + htcp_reset(&net->cc_mod.htcp_ca); + net->ssthresh = htcp_recalc_ssthresh(net); +- net->cwnd = net->mtu; ++ net->cwnd = SCTP_CWND_SIZE; + net->partial_bytes_acked = 0; + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX); +@@ -2400,7 +2364,7 @@ sctp_htcp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, + /* here back off the timer as well, to slow us down */ + net->RTO <<= 1; + } +- net->cwnd = net->ssthresh; ++ net->cwnd = SCTP_CWND_SIZE; + 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); +diff --git a/usrsctplib/netinet/sctp_constants.h b/usrsctplib/netinet/sctp_constants.h +index 038a340..af875bf 100755 +--- a/usrsctplib/netinet/sctp_constants.h ++++ b/usrsctplib/netinet/sctp_constants.h +@@ -619,7 +619,7 @@ extern void getwintimeofday(struct timeval *tv); + #define SCTP_SEND_SEC 1 + + /* recv timer def = 200ms */ +-#define SCTP_RECV_MSEC 200 ++#define SCTP_RECV_MSEC 1 + + /* 30 seconds + RTO (in ms) */ + #define SCTP_HB_DEFAULT_MSEC 30000 +diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c +index b7e4aea..287c9b1 100755 +--- a/usrsctplib/netinet/sctp_input.c ++++ b/usrsctplib/netinet/sctp_input.c +@@ -67,6 +67,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 355135 2019-11-27 19:32:29Z tu + #define APPLE_FILE_NO 2 + #endif + ++__declspec( dllexport ) uint32_t cwnd_window = 0; ++__declspec( dllexport ) uint32_t cwr_window_tsn = 0; ++__declspec( dllexport ) uint32_t last_cwr_tsn = 0; ++ ++__declspec( dllexport ) uint32_t rtt_mtu = 0; + + static void + sctp_stop_all_cookie_timers(struct sctp_tcb *stcb) +@@ -5229,6 +5234,16 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, + (stcb->asoc.stream_queue_cnt == 0)) { + sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED); + } ++ ++// int smooth = (*netp)->lastsa >> SCTP_RTT_SHIFT; ++// sctp_smooth_rtt = smooth; ++ cwnd_window = (*netp)->cwnd; ++ ++ rtt_mtu = (*netp)->mtu; ++ ++ cwr_window_tsn = (*netp)->cwr_window_tsn; ++ last_cwr_tsn = (*netp)->last_cwr_tsn; ++ + break; + } + case SCTP_HEARTBEAT_REQUEST: +diff --git a/usrsctplib/netinet/sctp_sysctl.h b/usrsctplib/netinet/sctp_sysctl.h +index 3957e61..492df25 100755 +--- a/usrsctplib/netinet/sctp_sysctl.h ++++ b/usrsctplib/netinet/sctp_sysctl.h +@@ -306,7 +306,7 @@ struct sctp_sysctl { + #define SCTPCTL_PMTU_RAISE_TIME_DESC "Default PMTU raise timer in seconds" + #define SCTPCTL_PMTU_RAISE_TIME_MIN 0 + #define SCTPCTL_PMTU_RAISE_TIME_MAX 0xFFFFFFFF +-#define SCTPCTL_PMTU_RAISE_TIME_DEFAULT SCTP_DEF_PMTU_RAISE_SEC ++#define SCTPCTL_PMTU_RAISE_TIME_DEFAULT SCTPCTL_PMTU_RAISE_TIME_MIN + + /* shutdown_guard_time: Default shutdown guard timer in seconds */ + #define SCTPCTL_SHUTDOWN_GUARD_TIME_DESC "Shutdown guard timer in seconds (0 means 5 times RTO.Max)" +@@ -354,19 +354,19 @@ struct sctp_sysctl { + #define SCTPCTL_INIT_RTX_MAX_DESC "Default maximum number of retransmissions for INIT chunks" + #define SCTPCTL_INIT_RTX_MAX_MIN 0 + #define SCTPCTL_INIT_RTX_MAX_MAX 0xFFFFFFFF +-#define SCTPCTL_INIT_RTX_MAX_DEFAULT SCTP_DEF_MAX_INIT ++#define SCTPCTL_INIT_RTX_MAX_DEFAULT SCTPCTL_INIT_RTX_MAX_MAX + + /* assoc_rtx_max: Default maximum number of retransmissions per association */ + #define SCTPCTL_ASSOC_RTX_MAX_DESC "Default maximum number of retransmissions per association" + #define SCTPCTL_ASSOC_RTX_MAX_MIN 0 + #define SCTPCTL_ASSOC_RTX_MAX_MAX 0xFFFFFFFF +-#define SCTPCTL_ASSOC_RTX_MAX_DEFAULT SCTP_DEF_MAX_SEND ++#define SCTPCTL_ASSOC_RTX_MAX_DEFAULT SCTPCTL_ASSOC_RTX_MAX_MAX + + /* path_rtx_max: Default maximum of retransmissions per path */ + #define SCTPCTL_PATH_RTX_MAX_DESC "Default maximum of retransmissions per path" + #define SCTPCTL_PATH_RTX_MAX_MIN 0 + #define SCTPCTL_PATH_RTX_MAX_MAX 0xFFFFFFFF +-#define SCTPCTL_PATH_RTX_MAX_DEFAULT SCTP_DEF_MAX_PATH_RTX ++#define SCTPCTL_PATH_RTX_MAX_DEFAULT SCTPCTL_PATH_RTX_MAX_MAX + + /* path_pf_threshold: threshold for considering the path potentially failed */ + #define SCTPCTL_PATH_PF_THRESHOLD_DESC "Default potentially failed threshold" +diff --git a/usrsctplib/netinet/sctp_usrreq.c b/usrsctplib/netinet/sctp_usrreq.c +index 6a19f62..8c3048e 100755 +--- a/usrsctplib/netinet/sctp_usrreq.c ++++ b/usrsctplib/netinet/sctp_usrreq.c +@@ -7796,10 +7796,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, + 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); +- } ++ net->cwnd = SCTP_CWND_SIZE; + } + } + } +diff --git a/usrsctplib/netinet/sctp_var.h b/usrsctplib/netinet/sctp_var.h +index ead9e9c..b066d6f 100755 +--- a/usrsctplib/netinet/sctp_var.h ++++ b/usrsctplib/netinet/sctp_var.h +@@ -516,4 +516,6 @@ int sctp_accept(struct socket *, struct mbuf *); + + #endif /* _KERNEL */ + ++#define SCTP_CWND_SIZE 2621440 ++ + #endif /* !_NETINET_SCTP_VAR_H_ */ +diff --git a/usrsctplib/netinet/sctputil.c b/usrsctplib/netinet/sctputil.c +index 001a2b3..da68d1a 100755 +--- a/usrsctplib/netinet/sctputil.c ++++ b/usrsctplib/netinet/sctputil.c +@@ -86,6 +86,10 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 353518 2019-10-14 20:32:11Z tuex + #endif + #endif + ++//extern "C" uint32_t sctp_smooth_rtt; ++ ++__declspec( dllexport ) uint32_t sctp_smooth_rtt = 0; ++ + extern const struct sctp_cc_functions sctp_cc_functions[]; + extern const struct sctp_ss_functions sctp_ss_functions[]; + +@@ -2690,6 +2694,9 @@ sctp_calculate_rto(struct sctp_tcb *stcb, + if (new_rto > stcb->asoc.maxrto) { + new_rto = stcb->asoc.maxrto; + } ++ ++ sctp_smooth_rtt = net->lastsa >> SCTP_RTT_SHIFT; ++ + net->RTO = new_rto; + return (1); + } +-- +2.22.0.windows.1 + diff --git a/usrsctplib.patch b/usrsctplib.patch index 7eb195c..bc83143 100644 --- a/usrsctplib.patch +++ b/usrsctplib.patch @@ -1,7 +1,13 @@ diff --git a/usrsctplib/netinet/sctp_cc_functions.c b/usrsctplib/netinet/sctp_cc_functions.c -index 0139057..5772134 100755 +index e53e4d7..12c6594 100755 --- a/usrsctplib/netinet/sctp_cc_functions.c +++ b/usrsctplib/netinet/sctp_cc_functions.c +@@ -1,4 +1,4 @@ +-/*- ++/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. @@ -64,10 +64,7 @@ sctp_enforce_cwnd_limit(struct sctp_association *assoc, struct sctp_nets *net) if ((assoc->max_cwnd > 0) && (net->cwnd > assoc->max_cwnd) && @@ -10,11 +16,11 @@ index 0139057..5772134 100755 - if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) { - net->cwnd = net->mtu - sizeof(struct sctphdr); - } -+ net->cwnd = SCTP_CWND_SIZE ; ++ net->cwnd = SCTP_CWND_SIZE; } } -@@ -79,26 +76,12 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -79,26 +76,15 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) assoc = &stcb->asoc; cwnd_in_mtu = SCTP_BASE_SYSCTL(sctp_initial_cwnd); @@ -38,16 +44,19 @@ index 0139057..5772134 100755 - net->cwnd = net->mtu - sizeof(struct sctphdr); - } - } -+ ++ net->cwnd = SCTP_CWND_SIZE; ++ ++ /* ++ * We take the minimum of the burst limit and the ++ * initial congestion window. ++ */ + if ((cwnd_in_mtu != 0) && (assoc->max_burst > 0) && (cwnd_in_mtu > assoc->max_burst)) + cwnd_in_mtu = assoc->max_burst; -+ -+ net->cwnd = SCTP_CWND_SIZE; + sctp_enforce_cwnd_limit(assoc, net); net->ssthresh = assoc->peers_rwnd; #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 -@@ -194,7 +177,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb, +@@ -194,7 +180,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb, net->ssthresh = 2 * net->mtu; } } @@ -56,7 +65,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(asoc, net); #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE5(sctp, cwnd, net, fr, -@@ -309,7 +292,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb +@@ -309,7 +295,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb probepoint); #endif if (net->cwnd > (4 * net->mtu)) { @@ -65,7 +74,7 @@ index 0139057..5772134 100755 net->cc_mod.rtcc.vol_reduce++; } else { net->cc_mod.rtcc.step_cnt = 0; -@@ -391,7 +374,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb +@@ -391,7 +377,7 @@ cc_bw_same(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_t nb ((net->cc_mod.rtcc.step_cnt % net->cc_mod.rtcc.steady_step) == 0))) { /* Try a step down */ if (net->cwnd > (4 * net->mtu)) { @@ -74,7 +83,7 @@ index 0139057..5772134 100755 net->cc_mod.rtcc.vol_reduce++; return (1); } else { -@@ -478,7 +461,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ +@@ -478,7 +464,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ */ if ((net->cc_mod.rtcc.vol_reduce) && (inst_ind != SCTP_INST_GAINING)) { @@ -83,7 +92,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(&stcb->asoc, net); net->cc_mod.rtcc.vol_reduce--; } -@@ -514,7 +497,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ +@@ -514,7 +500,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ #endif if ((net->cc_mod.rtcc.vol_reduce) && (inst_ind != SCTP_INST_GAINING)) { @@ -92,7 +101,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(&stcb->asoc, net); net->cc_mod.rtcc.vol_reduce--; } -@@ -550,7 +533,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ +@@ -550,7 +536,7 @@ cc_bw_decrease(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, uint64_ #endif if ((net->cc_mod.rtcc.vol_reduce) && (inst_ind != SCTP_INST_GAINING)) { @@ -101,7 +110,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(&stcb->asoc, net); net->cc_mod.rtcc.vol_reduce--; } -@@ -981,7 +964,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb, +@@ -981,7 +967,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb, } break; } @@ -110,7 +119,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, incr, -@@ -1049,7 +1032,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb, +@@ -1049,7 +1035,7 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb, incr = net->mtu; break; } @@ -119,7 +128,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(asoc, net); #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE5(sctp, cwnd, net, ack, -@@ -1091,7 +1074,7 @@ sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_n +@@ -1091,7 +1077,7 @@ sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_n old_cwnd = net->cwnd; #endif @@ -128,7 +137,7 @@ index 0139057..5772134 100755 #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE5(sctp, cwnd, net, ack, stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net, -@@ -1163,7 +1146,7 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -1163,7 +1149,7 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net) } else { net->ssthresh = max(net->cwnd / 2, 4 * net->mtu); } @@ -137,11 +146,10 @@ index 0139057..5772134 100755 net->partial_bytes_acked = 0; #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE5(sctp, cwnd, net, to, -@@ -1187,14 +1170,8 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * - if (in_window == 0) { +@@ -1188,13 +1174,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * /* Go to CA with the cwnd at the point we sent * the TSN that was marked with a CE. -- */ + */ - if (net->ecn_prev_cwnd < net->cwnd) { - /* Restore to prev cwnd */ - net->cwnd = net->ecn_prev_cwnd - (net->mtu * num_pkt_lost); @@ -149,12 +157,11 @@ index 0139057..5772134 100755 - /* Just cut in 1/2 */ - net->cwnd /= 2; - } -+ */ + net->cwnd = SCTP_CWND_SIZE; /* Drop to CA */ net->ssthresh = net->cwnd - (num_pkt_lost * net->mtu); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { -@@ -1203,7 +1180,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * +@@ -1203,7 +1183,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * } else { /* Further tuning down required over the drastic original cut */ net->ssthresh -= (net->mtu * num_pkt_lost); @@ -163,7 +170,7 @@ index 0139057..5772134 100755 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); } -@@ -1219,7 +1196,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * +@@ -1219,7 +1199,7 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets * /* here back off the timer as well, to slow us down */ net->RTO <<= 1; } @@ -172,7 +179,7 @@ index 0139057..5772134 100755 #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE5(sctp, cwnd, net, ecn, stcb->asoc.my_vtag, -@@ -1283,7 +1260,7 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, +@@ -1283,7 +1263,7 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, * undo any cwnd adjustment that the sack * might have made */ @@ -181,7 +188,7 @@ index 0139057..5772134 100755 } /* Now how much of that is mine? */ seg_inflight = net->flight_size / net->mtu; -@@ -1310,12 +1287,8 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, +@@ -1310,12 +1290,8 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, * had a sack before this packet). minus what ever * portion of the overage is my fault. */ @@ -195,28 +202,26 @@ index 0139057..5772134 100755 /* force into CA */ net->ssthresh = net->cwnd - 1; } else { -@@ -1328,16 +1301,11 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, +@@ -1328,15 +1304,15 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, (stcb->asoc.max_burst * net->mtu < incr)) { incr = stcb->asoc.max_burst * net->mtu; } - net->cwnd += incr; -- } -- if (net->cwnd > bw_avail) { -- /* We can't exceed the pipe size */ ++ net->cwnd = SCTP_CWND_SIZE; + } + 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 = SCTP_CWND_SIZE; + } + if (net->cwnd < net->mtu) { + /* We always have 1 MTU */ - net->cwnd = net->mtu; + net->cwnd = SCTP_CWND_SIZE; } -+ -+ net->cwnd = SCTP_CWND_SIZE; -+ sctp_enforce_cwnd_limit(&stcb->asoc, net); if (net->cwnd - old_cwnd != 0) { - /* log only changes */ -@@ -1364,7 +1332,7 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb, +@@ -1364,7 +1340,7 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb, if (net->ssthresh < net->cwnd) net->ssthresh = net->cwnd; if (burst_limit) { @@ -225,7 +230,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(&stcb->asoc, net); #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 SDT_PROBE5(sctp, cwnd, net, bl, -@@ -1484,7 +1452,7 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb, +@@ -1484,7 +1460,7 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb, } if (net->cwnd > cwnd) { /* Only set if we are not a timeout (i.e. down to 1 mtu) */ @@ -234,7 +239,7 @@ index 0139057..5772134 100755 } } } -@@ -1712,11 +1680,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -1712,11 +1688,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net) if (cur_val < sctp_cwnd_adjust[0].cwnd) { /* normal mode */ @@ -247,7 +252,7 @@ index 0139057..5772134 100755 } else { for (i = net->last_hs_used; i < SCTP_HS_TABLE_SIZE; i++) { if (cur_val < sctp_cwnd_adjust[i].cwnd) { -@@ -1726,7 +1690,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -1726,7 +1698,7 @@ sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net) } net->last_hs_used = indx; incr = (((int32_t)sctp_cwnd_adjust[indx].increase) << 10); @@ -256,7 +261,7 @@ index 0139057..5772134 100755 } sctp_enforce_cwnd_limit(&stcb->asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { -@@ -1747,12 +1711,12 @@ sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -1747,12 +1719,12 @@ sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net) if (net->ssthresh < (net->mtu * 2)) { net->ssthresh = 2 * net->mtu; } @@ -271,7 +276,7 @@ index 0139057..5772134 100755 /* now where are we */ indx = net->last_hs_used; cur_val = net->cwnd >> 10; -@@ -1912,7 +1876,7 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb, +@@ -1912,7 +1884,7 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb, if ((net->flight_size + net->net_ack >= net->cwnd) && (net->partial_bytes_acked >= net->cwnd)) { net->partial_bytes_acked -= net->cwnd; @@ -280,7 +285,7 @@ index 0139057..5772134 100755 sctp_enforce_cwnd_limit(asoc, net); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, net->mtu, -@@ -2138,14 +2102,14 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -2138,14 +2110,14 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net) /* We are in slow start */ if (net->flight_size + net->net_ack >= net->cwnd) { if (net->net_ack > (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) { @@ -297,7 +302,7 @@ index 0139057..5772134 100755 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_FROM_SS); -@@ -2171,7 +2135,7 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -2171,7 +2143,7 @@ htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net) * Does SCTP have a cwnd clamp? * if (net->snd_cwnd < net->snd_cwnd_clamp) - Nope (RRS). */ @@ -306,7 +311,7 @@ index 0139057..5772134 100755 net->partial_bytes_acked = 0; sctp_enforce_cwnd_limit(&stcb->asoc, net); htcp_alpha_update(&net->cc_mod.htcp_ca); -@@ -2217,7 +2181,7 @@ sctp_htcp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) +@@ -2217,7 +2189,7 @@ 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. */ @@ -315,7 +320,7 @@ index 0139057..5772134 100755 net->ssthresh = stcb->asoc.peers_rwnd; sctp_enforce_cwnd_limit(&stcb->asoc, net); htcp_init(net); -@@ -2320,7 +2284,7 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb, +@@ -2320,7 +2292,7 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb, /* JRS - reset as if state were changed */ htcp_reset(&net->cc_mod.htcp_ca); net->ssthresh = htcp_recalc_ssthresh(net); @@ -324,7 +329,7 @@ index 0139057..5772134 100755 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), -@@ -2376,7 +2340,7 @@ sctp_htcp_cwnd_update_after_timeout(struct sctp_tcb *stcb, +@@ -2376,7 +2348,7 @@ sctp_htcp_cwnd_update_after_timeout(struct sctp_tcb *stcb, /* JRS - reset as if the state were being changed to timeout */ htcp_reset(&net->cc_mod.htcp_ca); net->ssthresh = htcp_recalc_ssthresh(net); @@ -333,7 +338,7 @@ index 0139057..5772134 100755 net->partial_bytes_acked = 0; if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX); -@@ -2400,7 +2364,7 @@ sctp_htcp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, +@@ -2400,7 +2372,7 @@ sctp_htcp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, /* here back off the timer as well, to slow us down */ net->RTO <<= 1; } @@ -343,10 +348,10 @@ index 0139057..5772134 100755 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); diff --git a/usrsctplib/netinet/sctp_constants.h b/usrsctplib/netinet/sctp_constants.h -index 038a340..af875bf 100755 +index f9a87a4..74b72e9 100755 --- a/usrsctplib/netinet/sctp_constants.h +++ b/usrsctplib/netinet/sctp_constants.h -@@ -619,7 +619,7 @@ extern void getwintimeofday(struct timeval *tv); +@@ -615,7 +615,7 @@ extern void getwintimeofday(struct timeval *tv); #define SCTP_SEND_SEC 1 /* recv timer def = 200ms */ @@ -356,10 +361,10 @@ index 038a340..af875bf 100755 /* 30 seconds + RTO (in ms) */ #define SCTP_HB_DEFAULT_MSEC 30000 diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c -index b7e4aea..287c9b1 100755 +index c62bb85..0ac48b2 100755 --- a/usrsctplib/netinet/sctp_input.c +++ b/usrsctplib/netinet/sctp_input.c -@@ -67,6 +67,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 355135 2019-11-27 19:32:29Z tu +@@ -64,6 +64,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 334725 2018-06-06 19:27:06Z tu #define APPLE_FILE_NO 2 #endif @@ -371,7 +376,7 @@ index b7e4aea..287c9b1 100755 static void sctp_stop_all_cookie_timers(struct sctp_tcb *stcb) -@@ -5229,6 +5234,16 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, +@@ -5222,6 +5227,16 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, (stcb->asoc.stream_queue_cnt == 0)) { sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED); } @@ -389,10 +394,10 @@ index b7e4aea..287c9b1 100755 } case SCTP_HEARTBEAT_REQUEST: diff --git a/usrsctplib/netinet/sctp_sysctl.h b/usrsctplib/netinet/sctp_sysctl.h -index 3957e61..492df25 100755 +index 4f10ff6..5658208 100755 --- a/usrsctplib/netinet/sctp_sysctl.h +++ b/usrsctplib/netinet/sctp_sysctl.h -@@ -306,7 +306,7 @@ struct sctp_sysctl { +@@ -305,7 +305,7 @@ struct sctp_sysctl { #define SCTPCTL_PMTU_RAISE_TIME_DESC "Default PMTU raise timer in seconds" #define SCTPCTL_PMTU_RAISE_TIME_MIN 0 #define SCTPCTL_PMTU_RAISE_TIME_MAX 0xFFFFFFFF @@ -401,8 +406,8 @@ index 3957e61..492df25 100755 /* shutdown_guard_time: Default shutdown guard timer in seconds */ #define SCTPCTL_SHUTDOWN_GUARD_TIME_DESC "Shutdown guard timer in seconds (0 means 5 times RTO.Max)" -@@ -354,19 +354,19 @@ struct sctp_sysctl { - #define SCTPCTL_INIT_RTX_MAX_DESC "Default maximum number of retransmissions for INIT chunks" +@@ -353,19 +353,19 @@ struct sctp_sysctl { + #define SCTPCTL_INIT_RTX_MAX_DESC "Default maximum number of retransmission for INIT chunks" #define SCTPCTL_INIT_RTX_MAX_MIN 0 #define SCTPCTL_INIT_RTX_MAX_MAX 0xFFFFFFFF -#define SCTPCTL_INIT_RTX_MAX_DEFAULT SCTP_DEF_MAX_INIT @@ -425,10 +430,10 @@ index 3957e61..492df25 100755 /* path_pf_threshold: threshold for considering the path potentially failed */ #define SCTPCTL_PATH_PF_THRESHOLD_DESC "Default potentially failed threshold" diff --git a/usrsctplib/netinet/sctp_usrreq.c b/usrsctplib/netinet/sctp_usrreq.c -index 6a19f62..8c3048e 100755 +index bb5ea8e..ff94597 100755 --- a/usrsctplib/netinet/sctp_usrreq.c +++ b/usrsctplib/netinet/sctp_usrreq.c -@@ -7796,10 +7796,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, +@@ -7661,10 +7661,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { if ((net->cwnd > stcb->asoc.max_cwnd) && (net->cwnd > (net->mtu - sizeof(struct sctphdr)))) { @@ -441,7 +446,7 @@ index 6a19f62..8c3048e 100755 } } diff --git a/usrsctplib/netinet/sctp_var.h b/usrsctplib/netinet/sctp_var.h -index ead9e9c..b066d6f 100755 +index bc4afe9..a1e53fe 100755 --- a/usrsctplib/netinet/sctp_var.h +++ b/usrsctplib/netinet/sctp_var.h @@ -516,4 +516,6 @@ int sctp_accept(struct socket *, struct mbuf *); @@ -452,10 +457,10 @@ index ead9e9c..b066d6f 100755 + #endif /* !_NETINET_SCTP_VAR_H_ */ diff --git a/usrsctplib/netinet/sctputil.c b/usrsctplib/netinet/sctputil.c -index 001a2b3..da68d1a 100755 +index 1134b50..d0a204e 100755 --- a/usrsctplib/netinet/sctputil.c +++ b/usrsctplib/netinet/sctputil.c -@@ -86,6 +86,10 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 353518 2019-10-14 20:32:11Z tuex +@@ -85,6 +85,10 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 334286 2018-05-28 13:31:47Z tuex #endif #endif @@ -466,16 +471,15 @@ index 001a2b3..da68d1a 100755 extern const struct sctp_cc_functions sctp_cc_functions[]; extern const struct sctp_ss_functions sctp_ss_functions[]; -@@ -2690,6 +2694,9 @@ sctp_calculate_rto(struct sctp_tcb *stcb, +@@ -2651,6 +2655,9 @@ sctp_calculate_rto(struct sctp_tcb *stcb, if (new_rto > stcb->asoc.maxrto) { new_rto = stcb->asoc.maxrto; } + + sctp_smooth_rtt = net->lastsa >> SCTP_RTT_SHIFT; + - net->RTO = new_rto; - return (1); + /* we are now returning the RTO */ + return (new_rto); } --- -2.22.0.windows.1 + diff --git a/webrtc-85.patch b/webrtc-85.patch new file mode 100644 index 0000000..30065d3 --- /dev/null +++ b/webrtc-85.patch @@ -0,0 +1,290 @@ +diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h +index 2664af4e5e..a28dd69f3a 100644 +--- a/api/peer_connection_interface.h ++++ b/api/peer_connection_interface.h +@@ -1244,6 +1244,7 @@ class PeerConnectionObserver { + // The heuristics for defining what constitutes "interesting" are + // implementation-defined. + virtual void OnInterestingUsage(int usage_pattern) {} ++ virtual void OnAllConnectionDestroyed() {} + }; + + // PeerConnectionDependencies holds all of PeerConnections dependencies. +diff --git a/p2p/base/ice_transport_internal.h b/p2p/base/ice_transport_internal.h +index b735a1a742..e69bd8b58d 100644 +--- a/p2p/base/ice_transport_internal.h ++++ b/p2p/base/ice_transport_internal.h +@@ -312,6 +312,8 @@ class RTC_EXPORT IceTransportInternal : public rtc::PacketTransportInternal { + + // Invoked when the transport is being destroyed. + sigslot::signal1 SignalDestroyed; ++ ++ sigslot::signal<> SignalAllConectionDestroyed; + }; + + } // namespace cricket +diff --git a/p2p/base/p2p_constants.cc b/p2p/base/p2p_constants.cc +index 3414939a6f..b8f60f9108 100644 +--- a/p2p/base/p2p_constants.cc ++++ b/p2p/base/p2p_constants.cc +@@ -47,7 +47,7 @@ const int MIN_CHECK_RECEIVING_INTERVAL = 50; + const int RECEIVING_TIMEOUT = MIN_CHECK_RECEIVING_INTERVAL * 50; + const int RECEIVING_SWITCHING_DELAY = 1000; + const int BACKUP_CONNECTION_PING_INTERVAL = 25 * 1000; +-const int REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; ++const int REGATHER_ON_FAILED_NETWORKS_INTERVAL = 30 * 1000; + + // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) + // for pinging. When the socket is writable, we will use only 1 Kbps because we +diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc +index 6f0df04150..fd792a6dc6 100644 +--- a/p2p/base/p2p_transport_channel.cc ++++ b/p2p/base/p2p_transport_channel.cc +@@ -1766,6 +1766,7 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn, + GetProtocolOverhead(selected_connection_->local_candidate().protocol()); + } else { + RTC_LOG(LS_INFO) << ToString() << ": No selected connection"; ++ SignalAllConectionDestroyed(); + } + + if (field_trials_.send_ping_on_switch_ice_controlling && +diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc +index b13896c4bc..19b7a1b5c9 100644 +--- a/p2p/base/port_allocator.cc ++++ b/p2p/base/port_allocator.cc +@@ -205,6 +205,15 @@ bool PortAllocator::SetConfiguration( + return true; + } + ++bool PortAllocator::SetConfigurationFromTitan(const ServerAddresses& stun_servers, ++ const std::vector& turn_servers, ++ int candidate_pool_size, ++ bool prune_turn_ports, ++ webrtc::TurnCustomizer* turn_customizer) ++{ ++ return SetConfiguration(stun_servers, turn_servers, candidate_pool_size, prune_turn_ports, turn_customizer); ++} ++ + std::unique_ptr PortAllocator::CreateSession( + const std::string& content_name, + int component, +diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h +index 4bbe56c0b5..7d30882dce 100644 +--- a/p2p/base/port_allocator.h ++++ b/p2p/base/port_allocator.h +@@ -374,6 +374,12 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { + const absl::optional& + stun_candidate_keepalive_interval = absl::nullopt); + ++ bool SetConfigurationFromTitan(const ServerAddresses& stun_servers, ++ const std::vector& turn_servers, ++ int candidate_pool_size, ++ bool prune_turn_ports, ++ webrtc::TurnCustomizer* turn_customizer = nullptr); ++ + const ServerAddresses& stun_servers() const { + CheckRunOnValidThreadIfInitialized(); + return stun_servers_; +diff --git a/p2p/base/stun_port.cc b/p2p/base/stun_port.cc +index 4e1a1f6a97..17955f114c 100644 +--- a/p2p/base/stun_port.cc ++++ b/p2p/base/stun_port.cc +@@ -373,10 +373,6 @@ void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket, + // applications which absolutely requires a HOST candidate. + rtc::SocketAddress addr = address; + +- // If MaybeSetDefaultLocalAddress fails, we keep the "any" IP so that at +- // least the port is listening. +- MaybeSetDefaultLocalAddress(&addr); +- + AddAddress(addr, addr, rtc::SocketAddress(), UDP_PROTOCOL_NAME, "", "", + LOCAL_PORT_TYPE, ICE_TYPE_PREFERENCE_HOST, 0, "", false); + MaybePrepareStunCandidate(); +diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc +index bb640d9498..86fec2d155 100644 +--- a/p2p/client/basic_port_allocator.cc ++++ b/p2p/client/basic_port_allocator.cc +@@ -681,11 +681,11 @@ void BasicPortAllocatorSession::OnAllocate() { + std::vector BasicPortAllocatorSession::GetNetworks() { + RTC_DCHECK_RUN_ON(network_thread_); + std::vector networks; +- rtc::NetworkManager* network_manager = allocator_->network_manager(); +- RTC_DCHECK(network_manager != nullptr); ++ _network_manager = allocator_->network_manager(); ++ RTC_DCHECK(_network_manager != nullptr); + // If the network permission state is BLOCKED, we just act as if the flag has + // been passed in. +- if (network_manager->enumeration_permission() == ++ if (_network_manager->enumeration_permission() == + rtc::NetworkManager::ENUMERATION_BLOCKED) { + set_flags(flags() | PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION); + } +@@ -694,15 +694,15 @@ std::vector BasicPortAllocatorSession::GetNetworks() { + // traffic by OS is also used here to avoid any local or public IP leakage + // during stun process. + if (flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) { +- network_manager->GetAnyAddressNetworks(&networks); ++ _network_manager->GetAnyAddressNetworks(&networks); + } else { +- network_manager->GetNetworks(&networks); ++ _network_manager->GetNetworks(&networks); + // If network enumeration fails, use the ANY address as a fallback, so we + // can at least try gathering candidates using the default route chosen by + // the OS. Or, if the PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is + // set, we'll use ANY address candidates either way. + if (networks.empty() || flags() & PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS) { +- network_manager->GetAnyAddressNetworks(&networks); ++ _network_manager->GetAnyAddressNetworks(&networks); + } + } + // Filter out link-local networks if needed. +@@ -965,7 +965,34 @@ void BasicPortAllocatorSession::OnCandidateReady(Port* port, + candidates.push_back(allocator_->SanitizeCandidate(c)); + SignalCandidatesReady(this, candidates); + } else { +- RTC_LOG(LS_INFO) << "Discarding candidate because it doesn't match filter."; ++ if (c.address().IsAnyIP()) { ++ std::vector candidates; ++ ++ std::vector networks; ++ _network_manager->GetNetworks(&networks); ++ ++ for (uint32_t i = 0; i < networks.size(); ++i) { ++ Candidate tmp_c = c; ++ rtc::SocketAddress addr = c.address(); ++ auto item = networks[i]; ++ auto ip = item->GetBestIP(); ++ addr.SetResolvedIP(ip); ++ ++ const auto foundation = Port::ComputeFoundation(c.type(), c.protocol(), c.relay_protocol(), addr); ++ tmp_c.set_foundation(foundation); ++ tmp_c.set_network_id(item->id()); ++ tmp_c.set_network_name(item->name()); ++ tmp_c.set_network_type(item->type()); ++ tmp_c.set_address(addr); ++ candidates.push_back(allocator_->SanitizeCandidate(tmp_c)); ++ } ++ ++ SignalCandidatesReady(this, candidates); ++ } ++ else ++ { ++ RTC_LOG(LS_INFO) << "Discarding candidate because it doesn't match filter. " << c.ToString(); ++ } + } + + // If we have pruned any port, maybe need to signal port allocation done. +diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h +index b27016a1dc..6856a4c5b3 100644 +--- a/p2p/client/basic_port_allocator.h ++++ b/p2p/client/basic_port_allocator.h +@@ -271,6 +271,7 @@ class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession, + std::vector ports_; + std::vector candidate_error_events_; + uint32_t candidate_filter_ = CF_ALL; ++ rtc::NetworkManager* _network_manager; + // Policy on how to prune turn ports, taken from the port allocator. + webrtc::PortPrunePolicy turn_port_prune_policy_; + SessionState state_ = SessionState::CLEARED; +diff --git a/pc/data_channel.cc b/pc/data_channel.cc +index ca6b6145cb..16867d5b9c 100644 +--- a/pc/data_channel.cc ++++ b/pc/data_channel.cc +@@ -802,6 +802,11 @@ bool DataChannel::QueueSendDataMessage(const DataBuffer& buffer) { + return false; + } + queued_send_data_.PushBack(std::make_unique(buffer)); ++ ++ // The buffer can have length zero, in which case there is no change. ++ if (observer_ && buffered_amount() > start_buffered_amount) { ++ observer_->OnBufferedAmountChange(start_buffered_amount); ++ } + return true; + } + +diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc +index dbe7435c02..fdbc4bdda5 100644 +--- a/pc/jsep_transport_controller.cc ++++ b/pc/jsep_transport_controller.cc +@@ -437,6 +437,9 @@ JsepTransportController::CreateDtlsTransport( + cricket::IceTransportInternal* ice) { + RTC_DCHECK(network_thread_->IsCurrent()); + ++ice->SignalAllConectionDestroyed.connect( ++ this, &JsepTransportController::OnSignalAllConectionDestroyed); ++ + std::unique_ptr dtls; + + if (config_.dtls_transport_factory) { +@@ -1421,4 +1424,11 @@ void JsepTransportController::OnDtlsHandshakeError( + SignalDtlsHandshakeError(error); + } + ++void JsepTransportController::OnSignalAllConectionDestroyed() { ++ ++ invoker_.AsyncInvoke(RTC_FROM_HERE, signaling_thread_, ++ [this] { ++ SignalAllConectionDestroyed(); ++ }); ++} + } // namespace webrtc +diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h +index 250501fd05..80b6322991 100644 +--- a/pc/jsep_transport_controller.h ++++ b/pc/jsep_transport_controller.h +@@ -223,6 +223,8 @@ class JsepTransportController : public sigslot::has_slots<> { + SignalIceCandidatePairChanged; + + sigslot::signal1 SignalDtlsHandshakeError; ++ ++ sigslot::signal<> SignalAllConectionDestroyed; + + private: + RTCError ApplyDescription_n(bool local, +@@ -396,6 +398,8 @@ class JsepTransportController : public sigslot::has_slots<> { + rtc::AsyncInvoker invoker_; + + RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController); ++ ++ void OnSignalAllConectionDestroyed(); + }; + + } // namespace webrtc +diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc +index 3def31a441..da12fc0d41 100644 +--- a/pc/peer_connection.cc ++++ b/pc/peer_connection.cc +@@ -1299,6 +1299,8 @@ bool PeerConnection::Initialize( + this, &PeerConnection::OnTransportControllerDtlsHandshakeError); + transport_controller_->SignalIceCandidatePairChanged.connect( + this, &PeerConnection::OnTransportControllerCandidateChanged); ++ transport_controller_->SignalAllConectionDestroyed.connect( ++ this, &PeerConnection::OnSignalAllConectionDestroyed); + + stats_.reset(new StatsCollector(this)); + stats_collector_ = RTCStatsCollector::Create(this); +@@ -7498,4 +7500,8 @@ RTCError PeerConnection::Rollback(SdpType sdp_type) { + return RTCError::OK(); + } + ++void PeerConnection::OnSignalAllConectionDestroyed() { ++ Observer()->OnAllConnectionDestroyed(); ++} ++ + } // namespace webrtc +diff --git a/pc/peer_connection.h b/pc/peer_connection.h +index a91dc9c042..4bc53bc04e 100644 +--- a/pc/peer_connection.h ++++ b/pc/peer_connection.h +@@ -1321,6 +1321,8 @@ class PeerConnection : public PeerConnectionInternal, + DataChannelController data_channel_controller_; + rtc::WeakPtrFactory weak_ptr_factory_ + RTC_GUARDED_BY(signaling_thread()); ++ ++ void OnSignalAllConectionDestroyed(); + }; + + } // namespace webrtc +-- +2.22.0.windows.1 + diff --git a/webrtc.patch b/webrtc.patch index 30065d3..486a8a9 100644 --- a/webrtc.patch +++ b/webrtc.patch @@ -1,110 +1,8 @@ -diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h -index 2664af4e5e..a28dd69f3a 100644 ---- a/api/peer_connection_interface.h -+++ b/api/peer_connection_interface.h -@@ -1244,6 +1244,7 @@ class PeerConnectionObserver { - // The heuristics for defining what constitutes "interesting" are - // implementation-defined. - virtual void OnInterestingUsage(int usage_pattern) {} -+ virtual void OnAllConnectionDestroyed() {} - }; - - // PeerConnectionDependencies holds all of PeerConnections dependencies. -diff --git a/p2p/base/ice_transport_internal.h b/p2p/base/ice_transport_internal.h -index b735a1a742..e69bd8b58d 100644 ---- a/p2p/base/ice_transport_internal.h -+++ b/p2p/base/ice_transport_internal.h -@@ -312,6 +312,8 @@ class RTC_EXPORT IceTransportInternal : public rtc::PacketTransportInternal { - - // Invoked when the transport is being destroyed. - sigslot::signal1 SignalDestroyed; -+ -+ sigslot::signal<> SignalAllConectionDestroyed; - }; - - } // namespace cricket -diff --git a/p2p/base/p2p_constants.cc b/p2p/base/p2p_constants.cc -index 3414939a6f..b8f60f9108 100644 ---- a/p2p/base/p2p_constants.cc -+++ b/p2p/base/p2p_constants.cc -@@ -47,7 +47,7 @@ const int MIN_CHECK_RECEIVING_INTERVAL = 50; - const int RECEIVING_TIMEOUT = MIN_CHECK_RECEIVING_INTERVAL * 50; - const int RECEIVING_SWITCHING_DELAY = 1000; - const int BACKUP_CONNECTION_PING_INTERVAL = 25 * 1000; --const int REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; -+const int REGATHER_ON_FAILED_NETWORKS_INTERVAL = 30 * 1000; - - // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) - // for pinging. When the socket is writable, we will use only 1 Kbps because we -diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc -index 6f0df04150..fd792a6dc6 100644 ---- a/p2p/base/p2p_transport_channel.cc -+++ b/p2p/base/p2p_transport_channel.cc -@@ -1766,6 +1766,7 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn, - GetProtocolOverhead(selected_connection_->local_candidate().protocol()); - } else { - RTC_LOG(LS_INFO) << ToString() << ": No selected connection"; -+ SignalAllConectionDestroyed(); - } - - if (field_trials_.send_ping_on_switch_ice_controlling && -diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc -index b13896c4bc..19b7a1b5c9 100644 ---- a/p2p/base/port_allocator.cc -+++ b/p2p/base/port_allocator.cc -@@ -205,6 +205,15 @@ bool PortAllocator::SetConfiguration( - return true; - } - -+bool PortAllocator::SetConfigurationFromTitan(const ServerAddresses& stun_servers, -+ const std::vector& turn_servers, -+ int candidate_pool_size, -+ bool prune_turn_ports, -+ webrtc::TurnCustomizer* turn_customizer) -+{ -+ return SetConfiguration(stun_servers, turn_servers, candidate_pool_size, prune_turn_ports, turn_customizer); -+} -+ - std::unique_ptr PortAllocator::CreateSession( - const std::string& content_name, - int component, -diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h -index 4bbe56c0b5..7d30882dce 100644 ---- a/p2p/base/port_allocator.h -+++ b/p2p/base/port_allocator.h -@@ -374,6 +374,12 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { - const absl::optional& - stun_candidate_keepalive_interval = absl::nullopt); - -+ bool SetConfigurationFromTitan(const ServerAddresses& stun_servers, -+ const std::vector& turn_servers, -+ int candidate_pool_size, -+ bool prune_turn_ports, -+ webrtc::TurnCustomizer* turn_customizer = nullptr); -+ - const ServerAddresses& stun_servers() const { - CheckRunOnValidThreadIfInitialized(); - return stun_servers_; -diff --git a/p2p/base/stun_port.cc b/p2p/base/stun_port.cc -index 4e1a1f6a97..17955f114c 100644 ---- a/p2p/base/stun_port.cc -+++ b/p2p/base/stun_port.cc -@@ -373,10 +373,6 @@ void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket, - // applications which absolutely requires a HOST candidate. - rtc::SocketAddress addr = address; - -- // If MaybeSetDefaultLocalAddress fails, we keep the "any" IP so that at -- // least the port is listening. -- MaybeSetDefaultLocalAddress(&addr); -- - AddAddress(addr, addr, rtc::SocketAddress(), UDP_PROTOCOL_NAME, "", "", - LOCAL_PORT_TYPE, ICE_TYPE_PREFERENCE_HOST, 0, "", false); - MaybePrepareStunCandidate(); -diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc -index bb640d9498..86fec2d155 100644 ---- a/p2p/client/basic_port_allocator.cc -+++ b/p2p/client/basic_port_allocator.cc -@@ -681,11 +681,11 @@ void BasicPortAllocatorSession::OnAllocate() { +diff --git a/p2p/client/basicportallocator.cc b/p2p/client/basicportallocator.cc +index 0c2fef3112..9ebd1d58da 100644 +--- a/p2p/client/basicportallocator.cc ++++ b/p2p/client/basicportallocator.cc +@@ -668,11 +668,11 @@ void BasicPortAllocatorSession::OnAllocate() { std::vector BasicPortAllocatorSession::GetNetworks() { RTC_DCHECK_RUN_ON(network_thread_); std::vector networks; @@ -119,7 +17,7 @@ index bb640d9498..86fec2d155 100644 rtc::NetworkManager::ENUMERATION_BLOCKED) { set_flags(flags() | PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION); } -@@ -694,15 +694,15 @@ std::vector BasicPortAllocatorSession::GetNetworks() { +@@ -679,15 +679,15 @@ std::vector BasicPortAllocatorSession::GetNetworks() { // traffic by OS is also used here to avoid any local or public IP leakage // during stun process. if (flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) { @@ -138,8 +36,8 @@ index bb640d9498..86fec2d155 100644 } } // Filter out link-local networks if needed. -@@ -965,7 +965,34 @@ void BasicPortAllocatorSession::OnCandidateReady(Port* port, - candidates.push_back(allocator_->SanitizeCandidate(c)); +@@ -916,7 +916,34 @@ void BasicPortAllocatorSession::OnCandidateReady(Port* port, + candidates.push_back(SanitizeCandidate(c)); SignalCandidatesReady(this, candidates); } else { - RTC_LOG(LS_INFO) << "Discarding candidate because it doesn't match filter."; @@ -156,13 +54,13 @@ index bb640d9498..86fec2d155 100644 + auto ip = item->GetBestIP(); + addr.SetResolvedIP(ip); + -+ const auto foundation = Port::ComputeFoundation(c.type(), c.protocol(), c.relay_protocol(), addr); ++ const auto foundation = ComputeFoundation(c.type(), c.protocol(), c.relay_protocol(), addr); + tmp_c.set_foundation(foundation); + tmp_c.set_network_id(item->id()); + tmp_c.set_network_name(item->name()); + tmp_c.set_network_type(item->type()); + tmp_c.set_address(addr); -+ candidates.push_back(allocator_->SanitizeCandidate(tmp_c)); ++ candidates.push_back(SanitizeCandidate(tmp_c)); + } + + SignalCandidatesReady(this, candidates); @@ -174,49 +72,165 @@ index bb640d9498..86fec2d155 100644 } // If we have pruned any port, maybe need to signal port allocation done. -diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h -index b27016a1dc..6856a4c5b3 100644 ---- a/p2p/client/basic_port_allocator.h -+++ b/p2p/client/basic_port_allocator.h -@@ -271,6 +271,7 @@ class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession, + +diff --git a/p2p/client/basicportallocator.h b/p2p/client/basicportallocator.h +index 672f3ddb7c..7b9dfcda1d 100644 +--- a/p2p/client/basicportallocator.h ++++ b/p2p/client/basicportallocator.h +@@ -270,6 +270,7 @@ class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession, + std::vector sequences_; std::vector ports_; - std::vector candidate_error_events_; uint32_t candidate_filter_ = CF_ALL; + rtc::NetworkManager* _network_manager; - // Policy on how to prune turn ports, taken from the port allocator. - webrtc::PortPrunePolicy turn_port_prune_policy_; + // Whether to prune low-priority ports, taken from the port allocator. + bool prune_turn_ports_; SessionState state_ = SessionState::CLEARED; -diff --git a/pc/data_channel.cc b/pc/data_channel.cc -index ca6b6145cb..16867d5b9c 100644 ---- a/pc/data_channel.cc -+++ b/pc/data_channel.cc -@@ -802,6 +802,11 @@ bool DataChannel::QueueSendDataMessage(const DataBuffer& buffer) { - return false; + +diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h +index 4a7b051b33..3aa891bcee 100644 +--- a/api/peerconnectioninterface.h ++++ b/api/peerconnectioninterface.h +@@ -1176,6 +1176,8 @@ class PeerConnectionObserver { + // The heuristics for defining what constitutes "interesting" are + // implementation-defined. + virtual void OnInterestingUsage(int usage_pattern) {} ++ ++ virtual void OnAllConnectionDestroyed() {} + }; + + // PeerConnectionDependencies holds all of PeerConnections dependencies. +diff --git a/p2p/base/p2pconstants.cc b/p2p/base/p2pconstants.cc +index 41d02dd968..d885419af4 100644 +--- a/p2p/base/p2pconstants.cc ++++ b/p2p/base/p2pconstants.cc +@@ -45,7 +45,7 @@ const int MIN_CHECK_RECEIVING_INTERVAL = 50; + const int RECEIVING_TIMEOUT = MIN_CHECK_RECEIVING_INTERVAL * 50; + const int RECEIVING_SWITCHING_DELAY = 1000; + const int BACKUP_CONNECTION_PING_INTERVAL = 25 * 1000; +-const int REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; ++const int REGATHER_ON_FAILED_NETWORKS_INTERVAL = 30 * 1000; + + // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) + // for pinging. When the socket is writable, we will use only 1 Kbps because we +diff --git a/p2p/base/p2ptransportchannel.cc b/p2p/base/p2ptransportchannel.cc +index 0d21613ba4..705b6702cd 100644 +--- a/p2p/base/p2ptransportchannel.cc ++++ b/p2p/base/p2ptransportchannel.cc +@@ -1855,6 +1855,7 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn) { + } else { + RTC_LOG(LS_INFO) << ToString() + << ": No selected connection"; ++ SignalAllConectionDestroyed(); + } + + SignalNetworkRouteChanged(network_route_); +diff --git a/p2p/base/p2ptransportchannel.h b/p2p/base/p2ptransportchannel.h +index abedd0bdd3..af60c536e7 100644 +--- a/p2p/base/p2ptransportchannel.h ++++ b/p2p/base/p2ptransportchannel.h +@@ -183,6 +183,8 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal { + return ss.Release(); } - queued_send_data_.PushBack(std::make_unique(buffer)); + ++ sigslot::signal<> SignalAllConectionDestroyed; + -+ // The buffer can have length zero, in which case there is no change. -+ if (observer_ && buffered_amount() > start_buffered_amount) { -+ observer_->OnBufferedAmountChange(start_buffered_amount); -+ } + private: + rtc::Thread* thread() const { return network_thread_; } + +diff --git a/p2p/base/port.cc b/p2p/base/port.cc +index 4d93b4f92f..bb0ce2df0b 100644 +--- a/p2p/base/port.cc ++++ b/p2p/base/port.cc +@@ -203,7 +203,7 @@ const char TCPTYPE_SIMOPEN_STR[] = "so"; + // then the foundation will be different. Two candidate pairs with + // the same foundation pairs are likely to have similar network + // characteristics. Foundations are used in the frozen algorithm. +-static std::string ComputeFoundation(const std::string& type, ++std::string ComputeFoundation(const std::string& type, + const std::string& protocol, + const std::string& relay_protocol, + const rtc::SocketAddress& base_address) { +diff --git a/p2p/base/port.h b/p2p/base/port.h +index ca4fedbbd8..b486bb2df1 100644 +--- a/p2p/base/port.h ++++ b/p2p/base/port.h +@@ -864,6 +864,10 @@ class ProxyConnection : public Connection { + int error_ = 0; + }; + ++std::string ComputeFoundation(const std::string& type, ++ const std::string& protocol, ++ const std::string& relay_protocol, ++ const rtc::SocketAddress& base_address); + } // namespace cricket + + #endif // P2P_BASE_PORT_H_ +diff --git a/p2p/base/portallocator.cc b/p2p/base/portallocator.cc +index 023e90be62..5a776fd5fb 100644 +--- a/p2p/base/portallocator.cc ++++ b/p2p/base/portallocator.cc +@@ -203,6 +203,15 @@ bool PortAllocator::SetConfiguration( return true; } -diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc -index dbe7435c02..fdbc4bdda5 100644 ---- a/pc/jsep_transport_controller.cc -+++ b/pc/jsep_transport_controller.cc -@@ -437,6 +437,9 @@ JsepTransportController::CreateDtlsTransport( - cricket::IceTransportInternal* ice) { - RTC_DCHECK(network_thread_->IsCurrent()); ++bool PortAllocator::SetConfigurationFromTitan(const ServerAddresses& stun_servers, ++ const std::vector& turn_servers, ++ int candidate_pool_size, ++ bool prune_turn_ports, ++ webrtc::TurnCustomizer* turn_customizer) ++{ ++ return SetConfiguration(stun_servers, turn_servers, candidate_pool_size, prune_turn_ports, turn_customizer); ++} ++ + std::unique_ptr PortAllocator::CreateSession( + const std::string& content_name, + int component, +diff --git a/p2p/base/portallocator.h b/p2p/base/portallocator.h +index 7026f2b2b6..410723f2c6 100644 +--- a/p2p/base/portallocator.h ++++ b/p2p/base/portallocator.h +@@ -365,6 +365,12 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { + const absl::optional& + stun_candidate_keepalive_interval = absl::nullopt); -+ice->SignalAllConectionDestroyed.connect( -+ this, &JsepTransportController::OnSignalAllConectionDestroyed); ++ bool SetConfigurationFromTitan(const ServerAddresses& stun_servers, ++ const std::vector& turn_servers, ++ int candidate_pool_size, ++ bool prune_turn_ports, ++ webrtc::TurnCustomizer* turn_customizer = nullptr); + - std::unique_ptr dtls; + const ServerAddresses& stun_servers() const { + CheckRunOnValidThreadIfInitialized(); + return stun_servers_; +diff --git a/p2p/base/stunport.cc b/p2p/base/stunport.cc +index 727312329e..e59471e7dd 100644 +--- a/p2p/base/stunport.cc ++++ b/p2p/base/stunport.cc +@@ -349,10 +349,6 @@ void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket, + // applications which absolutely requires a HOST candidate. + rtc::SocketAddress addr = address; - if (config_.dtls_transport_factory) { -@@ -1421,4 +1424,11 @@ void JsepTransportController::OnDtlsHandshakeError( +- // If MaybeSetDefaultLocalAddress fails, we keep the "any" IP so that at +- // least the port is listening. +- MaybeSetDefaultLocalAddress(&addr); +- + AddAddress(addr, addr, rtc::SocketAddress(), UDP_PROTOCOL_NAME, "", "", + LOCAL_PORT_TYPE, ICE_TYPE_PREFERENCE_HOST, 0, "", false); + MaybePrepareStunCandidate(); +diff --git a/pc/jseptransportcontroller.cc b/pc/jseptransportcontroller.cc +index 03899c3ceb..94a743618b 100644 +--- a/pc/jseptransportcontroller.cc ++++ b/pc/jseptransportcontroller.cc +@@ -426,6 +426,8 @@ JsepTransportController::CreateDtlsTransport(const std::string& transport_name, + auto ice = absl::make_unique( + transport_name, component, port_allocator_, async_resolver_factory_, + config_.event_log); ++ ice->SignalAllConectionDestroyed.connect( ++ this, &JsepTransportController::OnSignalAllConectionDestroyed); + dtls = absl::make_unique( + std::move(ice), config_.crypto_options, config_.event_log); + } +@@ -1494,4 +1496,12 @@ void JsepTransportController::OnDtlsHandshakeError( SignalDtlsHandshakeError(error); } @@ -227,21 +241,22 @@ index dbe7435c02..fdbc4bdda5 100644 + SignalAllConectionDestroyed(); + }); +} ++ } // namespace webrtc -diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h -index 250501fd05..80b6322991 100644 ---- a/pc/jsep_transport_controller.h -+++ b/pc/jsep_transport_controller.h -@@ -223,6 +223,8 @@ class JsepTransportController : public sigslot::has_slots<> { - SignalIceCandidatePairChanged; - +diff --git a/pc/jseptransportcontroller.h b/pc/jseptransportcontroller.h +index 653c4c97ec..ea58e7d97b 100644 +--- a/pc/jseptransportcontroller.h ++++ b/pc/jseptransportcontroller.h +@@ -206,6 +206,8 @@ class JsepTransportController : public sigslot::has_slots<> { sigslot::signal1 SignalDtlsHandshakeError; + + sigslot::signal<> SignalMediaTransportStateChanged; + + sigslot::signal<> SignalAllConectionDestroyed; private: RTCError ApplyDescription_n(bool local, -@@ -396,6 +398,8 @@ class JsepTransportController : public sigslot::has_slots<> { +@@ -369,6 +371,8 @@ class JsepTransportController : public sigslot::has_slots<> { rtc::AsyncInvoker invoker_; RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController); @@ -250,21 +265,21 @@ index 250501fd05..80b6322991 100644 }; } // namespace webrtc -diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc -index 3def31a441..da12fc0d41 100644 ---- a/pc/peer_connection.cc -+++ b/pc/peer_connection.cc -@@ -1299,6 +1299,8 @@ bool PeerConnection::Initialize( +diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc +index 4a5bd92d14..4b4ada4b6e 100644 +--- a/pc/peerconnection.cc ++++ b/pc/peerconnection.cc +@@ -987,6 +987,8 @@ bool PeerConnection::Initialize( + this, &PeerConnection::OnTransportControllerCandidatesRemoved); + transport_controller_->SignalDtlsHandshakeError.connect( this, &PeerConnection::OnTransportControllerDtlsHandshakeError); - transport_controller_->SignalIceCandidatePairChanged.connect( - this, &PeerConnection::OnTransportControllerCandidateChanged); + transport_controller_->SignalAllConectionDestroyed.connect( + this, &PeerConnection::OnSignalAllConectionDestroyed); - stats_.reset(new StatsCollector(this)); - stats_collector_ = RTCStatsCollector::Create(this); -@@ -7498,4 +7500,8 @@ RTCError PeerConnection::Rollback(SdpType sdp_type) { - return RTCError::OK(); + sctp_factory_ = factory_->CreateSctpTransportInternalFactory(); + +@@ -6628,4 +6630,8 @@ void PeerConnection::RequestUsagePatternReportForTesting() { + nullptr); } +void PeerConnection::OnSignalAllConectionDestroyed() { @@ -272,19 +287,18 @@ index 3def31a441..da12fc0d41 100644 +} + } // namespace webrtc -diff --git a/pc/peer_connection.h b/pc/peer_connection.h -index a91dc9c042..4bc53bc04e 100644 ---- a/pc/peer_connection.h -+++ b/pc/peer_connection.h -@@ -1321,6 +1321,8 @@ class PeerConnection : public PeerConnectionInternal, - DataChannelController data_channel_controller_; - rtc::WeakPtrFactory weak_ptr_factory_ - RTC_GUARDED_BY(signaling_thread()); -+ +diff --git a/pc/peerconnection.h b/pc/peerconnection.h +index b17881c862..2ff5d42aa7 100644 +--- a/pc/peerconnection.h ++++ b/pc/peerconnection.h +@@ -1127,6 +1127,8 @@ class PeerConnection : public PeerConnectionInternal, + + int usage_event_accumulator_ = 0; + bool return_histogram_very_quickly_ = false; ++ + void OnSignalAllConectionDestroyed(); }; } // namespace webrtc --- -2.22.0.windows.1 +