From 278120009720d2c990c51e34ad397c31c3ab1602 Mon Sep 17 00:00:00 2001 From: "Nils Ohlmeier [:drno]" Date: Wed, 21 Oct 2015 00:37:48 -0700 Subject: [PATCH] Bug 1208278 - improved STUN request timeout handling. r=bwc --HG-- extra : rebase_source : 5db4b680b26eb5c4e9e69443602e3a0d8fbca247 --- .../nICEr/src/stun/stun_client_ctx.c | 52 +++++++++++-------- .../nICEr/src/stun/stun_client_ctx.h | 2 +- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.c b/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.c index 640247225b5a..684709483252 100644 --- a/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.c +++ b/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.c @@ -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); } diff --git a/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.h b/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.h index b17424b2dbe1..042cd9c286f1 100644 --- a/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.h +++ b/media/mtransport/third_party/nICEr/src/stun/stun_client_ctx.h @@ -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;