Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

removed header logging. added jitter #87

Merged
merged 2 commits into from
Apr 18, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions source/secure_tunneling.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <aws/iotdevice/private/secure_tunneling_operations.h>

#include <aws/common/clock.h>
#include <aws/common/device_random.h>
#include <aws/common/string.h>
#include <aws/http/proxy.h>
#include <aws/http/request_response.h>
Expand Down Expand Up @@ -1198,10 +1199,9 @@ static int s_handshake_add_header(
}
AWS_LOGF_TRACE(
AWS_LS_IOTDEVICE_SECURE_TUNNELING,
"id=%p: Added header " PRInSTR " " PRInSTR " to websocket request",
"id=%p: Added header " PRInSTR " to websocket request",
(void *)secure_tunnel,
AWS_BYTE_CURSOR_PRI(header.name),
AWS_BYTE_CURSOR_PRI(header.value));
AWS_BYTE_CURSOR_PRI(header.name));
return AWS_OP_SUCCESS;
}

Expand Down Expand Up @@ -1378,23 +1378,53 @@ static void s_change_current_state_to_websocket_shutdown(struct aws_secure_tunne
}
}

static void s_update_reconnect_delay_for_pending_reconnect(struct aws_secure_tunnel *secure_tunnel) {
static uint64_t s_aws_secure_tunnel_compute_reconnect_backoff_no_jitter(struct aws_secure_tunnel *secure_tunnel) {
uint64_t retry_count = aws_min_u64(secure_tunnel->reconnect_count, 63);
return aws_mul_u64_saturating((uint64_t)1 << retry_count, MIN_RECONNECT_DELAY_MS);
}

uint64_t aws_secure_tunnel_random_in_range(uint64_t from, uint64_t to) {
uint64_t max = aws_max_u64(from, to);
uint64_t min = aws_min_u64(from, to);

uint64_t delay_ms = MIN_RECONNECT_DELAY_MS;
delay_ms = delay_ms << (int)secure_tunnel->reconnect_count;
/* Note: this contains several changes to the corresponding function in aws-c-io. Don't throw them away.
*
* 1. random range is now inclusive/closed: [from, to] rather than half-open [from, to)
* 2. as a corollary, diff == 0 => return min, not 0
*/
uint64_t diff = max - min;
if (!diff) {
return min;
}

uint64_t random_value = 0;
if (aws_device_random_u64(&random_value)) {
return min;
}

if (diff == UINT64_MAX) {
return random_value;
}

return min + random_value % (diff + 1); /* + 1 is safe due to previous check */
}

static uint64_t s_aws_secure_tunnel_compute_reconnect_backoff_full_jitter(struct aws_secure_tunnel *secure_tunnel) {
uint64_t non_jittered = s_aws_secure_tunnel_compute_reconnect_backoff_no_jitter(secure_tunnel);
return aws_secure_tunnel_random_in_range(0, non_jittered);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the range be [MIN_RECONNECT_DELAY_MS, non_jittered] ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think full jitter works in the entire range between 0 and max sleep. An argument could be made to use min but unless there's a good reason to, I think it just reduces the range of available times on a large scale reconnection event.

}

static void s_update_reconnect_delay_for_pending_reconnect(struct aws_secure_tunnel *secure_tunnel) {
uint64_t delay_ms = s_aws_secure_tunnel_compute_reconnect_backoff_full_jitter(secure_tunnel);
delay_ms = aws_min_u64(delay_ms, MAX_RECONNECT_DELAY_MS);
uint64_t now = (*secure_tunnel->vtable->get_current_time_fn)();

secure_tunnel->next_reconnect_time_ns =
aws_add_u64_saturating(now, aws_timestamp_convert(delay_ms, AWS_TIMESTAMP_MILLIS, AWS_TIMESTAMP_NANOS, NULL));

AWS_LOGF_DEBUG(
AWS_LS_IOTDEVICE_SECURE_TUNNELING,
"id=%p: next connection attempt in %" PRIu64 " milliseconds",
(void *)secure_tunnel,
delay_ms);

secure_tunnel->reconnect_count++;
}

Expand Down