Bug 1208278 - improved STUN request timeout handling. r=bwc

--HG--
extra : rebase_source : 5db4b680b26eb5c4e9e69443602e3a0d8fbca247
This commit is contained in:
Nils Ohlmeier [:drno] 2015-10-21 00:37:48 -07:00
Родитель 229f2b76cc
Коммит 2781200097
2 изменённых файлов: 31 добавлений и 23 удалений

Просмотреть файл

@ -73,33 +73,34 @@ int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *p
nr_socket_getaddr(sock,&ctx->my_addr);
nr_transport_addr_copy(&ctx->peer_addr,peer);
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) {
if (RTO != 0)
ctx->rto_ms = RTO;
else
ctx->rto_ms = 100;
if (RTO != 0) {
ctx->rto_ms = RTO;
} else if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) {
ctx->rto_ms = 100;
}
if (NR_reg_get_double(NR_STUN_REG_PREF_CLNT_RETRANSMIT_BACKOFF, &ctx->retransmission_backoff_factor))
ctx->retransmission_backoff_factor = 2.0;
ctx->retransmission_backoff_factor = 2.0;
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_MAXIMUM_TRANSMITS, &ctx->maximum_transmits))
ctx->maximum_transmits = 7;
ctx->maximum_transmits = 7;
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->final_retransmit_backoff_ms))
ctx->final_retransmit_backoff_ms = 16 * ctx->rto_ms;
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->maximum_transmits_timeout_ms))
ctx->maximum_transmits_timeout_ms = 16 * ctx->rto_ms;
ctx->mapped_addr_check_mask = NR_STUN_TRANSPORT_ADDR_CHECK_WILDCARD;
if (NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, &allow_loopback) ||
!allow_loopback) {
ctx->mapped_addr_check_mask |= NR_STUN_TRANSPORT_ADDR_CHECK_LOOPBACK;
}
ctx->mapped_addr_check_mask = NR_STUN_TRANSPORT_ADDR_CHECK_WILDCARD;
if (NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, &allow_loopback) ||
!allow_loopback) {
ctx->mapped_addr_check_mask |= NR_STUN_TRANSPORT_ADDR_CHECK_LOOPBACK;
}
/* If we are doing TCP, compute the maximum timeout as if
we retransmitted and then set the maximum number of
transmits to 1 and the timeout to maximum timeout*/
if (ctx->my_addr.protocol == IPPROTO_TCP) {
ctx->timeout_ms = ctx->final_retransmit_backoff_ms;
/* Because TCP is reliable there is only one final timeout value.
* We store the timeout value for TCP in here, because timeout_ms gets
* reset to 0 in client_reset() which gets called from client_start() */
ctx->maximum_transmits_timeout_ms = ctx->rto_ms *
pow(ctx->retransmission_backoff_factor,
ctx->maximum_transmits);
ctx->maximum_transmits = 1;
}
@ -393,18 +394,25 @@ static int nr_stun_client_send_request(nr_stun_client_ctx *ctx)
* response */
}
else {
if (ctx->request_ct < ctx->maximum_transmits) {
ctx->timeout_ms *= ctx->retransmission_backoff_factor;
ctx->timeout_ms += ctx->rto_ms;
if (ctx->request_ct >= ctx->maximum_transmits) {
/* Reliable transport only get here once. Unreliable get here for
* their final timeout. */
ctx->timeout_ms += ctx->maximum_transmits_timeout_ms;
}
else if (ctx->timeout_ms) {
/* exponential backoff */
ctx->timeout_ms *= ctx->retransmission_backoff_factor;
}
else {
ctx->timeout_ms += ctx->final_retransmit_backoff_ms;
/* initial timeout unreliable transports */
ctx->timeout_ms = ctx->rto_ms;
}
r_log(NR_LOG_STUN,LOG_DEBUG,"STUN-CLIENT(%s): Next timer will fire in %u ms",ctx->label, ctx->timeout_ms);
gettimeofday(&ctx->timer_set, 0);
assert(ctx->timeout_ms);
NR_ASYNC_TIMER_SET(ctx->timeout_ms, nr_stun_client_timer_expired_cb, ctx, &ctx->timer_handle);
}

Просмотреть файл

@ -170,7 +170,7 @@ struct nr_stun_client_ctx_ {
UINT4 rto_ms; /* retransmission time out */
double retransmission_backoff_factor;
UINT4 maximum_transmits;
UINT4 final_retransmit_backoff_ms;
UINT4 maximum_transmits_timeout_ms;
UINT4 mapped_addr_check_mask; /* What checks to run on mapped addresses */
int timeout_ms;
struct timeval timer_set;