diff --git a/include/libwebsockets/lws-retry.h b/include/libwebsockets/lws-retry.h index a7354ab1e..c74cf21c7 100644 --- a/include/libwebsockets/lws-retry.h +++ b/include/libwebsockets/lws-retry.h @@ -22,28 +22,18 @@ * IN THE SOFTWARE. */ -/* - * Specifies backoff ranges using a pair of uint32_t in ms for the min, max. - * - * The actual backoff timing is picked randomly within the range. - */ - -typedef struct lws_retry_range { - uint32_t min_ms; - uint32_t max_ms; -} lws_retry_range_t; - typedef struct lws_retry_bo { - const lws_retry_range_t *retry_ms_table; /* backoff range pair */ - uint16_t retry_ms_table_count; /* ranges in table */ + const uint32_t *retry_ms_table; /* base delay in ms */ + uint16_t retry_ms_table_count; /* entries in table */ uint16_t conceal_count; /* max retries to conceal */ + uint8_t jitter_percent; /* % additional random jitter */ } lws_retry_bo_t; /** * lws_retry_get_delay_ms() - get next delay from backoff table * * \param lws_context: the lws context (used for getting random) - * \param retry: the retry backoff table we are using + * \param retry: the retry backoff table we are using, or NULL for default * \param ctry: pointer to the try counter * \param conceal: pointer to flag set to nonzero if the try should be concealed * in terms of creating an error @@ -53,9 +43,12 @@ typedef struct lws_retry_bo { * set if the number of tries is less than the backoff table conceal_count, or * is zero if it exceeded it. This lets you conceal a certain number of retries * before alerting the caller there is a problem. + * + * If \p retry is NULL, a default of 3s + (0..300ms jitter) is used. If it's + * non-NULL but jitter_percent is 0, the default of 30% jitter is retained. */ LWS_VISIBLE LWS_EXTERN unsigned int lws_retry_get_delay_ms(struct lws_context *context, const lws_retry_bo_t *retry, - uint16_t *ctry, char *conceal); + uint16_t *ctry, char *conceal); diff --git a/lib/core-net/network.c b/lib/core-net/network.c index 09aa048db..91f098828 100644 --- a/lib/core-net/network.c +++ b/lib/core-net/network.c @@ -383,14 +383,12 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port, return port; } -static const lws_retry_range_t default_bo = { 3000, 7000 }; - unsigned int lws_retry_get_delay_ms(struct lws_context *context, - const lws_retry_bo_t *retry, uint16_t *ctry, char *conceal) + const lws_retry_bo_t *retry, uint16_t *ctry, + char *conceal) { - const lws_retry_range_t *r = &default_bo; - unsigned int ms; + uint64_t ms = 3000, pc = 30; /* sane-ish defaults if no retry table */ uint16_t ra; if (conceal) @@ -398,15 +396,20 @@ lws_retry_get_delay_ms(struct lws_context *context, if (retry) { if (*ctry < retry->retry_ms_table_count) - r = &retry->retry_ms_table[*ctry]; + ms = retry->retry_ms_table[*ctry]; else - r = &retry->retry_ms_table[ + ms = retry->retry_ms_table[ retry->retry_ms_table_count - 1]; + + /* if no percent given, use the default 30% */ + if (retry->jitter_percent) + pc = retry->jitter_percent; } - ms = r->min_ms; if (lws_get_random(context, &ra, sizeof(ra)) == sizeof(ra)) - ms += ((r->max_ms - ms) * ra) / 65535; + ms += ((ms * pc * ra) >> 16) / 100; + else + assert(0); if (*ctry < 0xffff) (*ctry)++;