added rtt and rtt deviation calculation for the tcp layer

This commit is contained in:
cozis
2023-08-29 12:56:23 +02:00
parent 6bfb514df7
commit 91f2526f15
10 changed files with 87 additions and 35 deletions
+3 -1
View File
@@ -223,8 +223,10 @@ static void arp_translation_table_seconds_passed(arp_translation_table_t *table,
}
}
void arp_seconds_passed(arp_state_t *state, size_t seconds)
void arp_ms_passed(arp_state_t *state, size_t ms)
{
size_t seconds = ms / 1000;
state->time += seconds;
// Scan through all of the timed-out entries
+1 -1
View File
@@ -124,5 +124,5 @@ void arp_resolve_mac(arp_state_t *state,
void *userp,
void (*callback)(void*, arp_resolution_status_t, mac_address_t));
void arp_seconds_passed(arp_state_t *state, size_t seconds);
void arp_ms_passed(arp_state_t *state, size_t ms);
void arp_change_output_buffer(arp_state_t *state, void *ptr, size_t max);
+1
View File
@@ -22,5 +22,6 @@ typedef struct {
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define ABS(X) ((X) < 0 ? -(X) : (X))
#endif /* MICROTCP_DEFS_H */
+2 -3
View File
@@ -29,7 +29,6 @@ static uint16_t calculate_checksum_ip(const void *src, size_t len)
return cpu_to_net_u16(~sum);
}
static ip_plugged_protocol_t *
find_protocol_with_id(ip_state_t *ip_state, uint8_t protocol)
{
@@ -125,10 +124,10 @@ void ip_change_output_buffer(ip_state_t *state, void *ptr, size_t max)
icmp_change_output_buffer(&state->icmp_state, (ip_packet_t*) ptr + 1, max - sizeof(ip_packet_t));
}
void ip_seconds_passed(ip_state_t *state, size_t seconds)
void ip_ms_passed(ip_state_t *state, size_t ms)
{
(void) state;
(void) seconds;
(void) ms;
}
int ip_send(ip_state_t *state, ip_protocol_t protocol,
+1 -1
View File
@@ -54,7 +54,7 @@ typedef struct {
ip_plugged_protocol_t plugged_protocols[IP_PLUGGED_PROTOCOLS_MAX];
} ip_state_t;
void ip_seconds_passed(ip_state_t *state, size_t seconds);
void ip_ms_passed(ip_state_t *state, size_t ms);
void ip_change_output_buffer(ip_state_t *state, void *ptr, size_t max);
void ip_init(ip_state_t *state, ip_address_t ip, void *send_data, void (*send)(void*, ip_address_t, size_t));
void ip_free(ip_state_t *state);
+18 -9
View File
@@ -105,7 +105,7 @@ struct microtcp_socket_t {
struct microtcp_t {
time_t last_update_time;
uint64_t last_update_time_ms;
#ifdef MICROTCP_BACKGROUND_THREAD
bool thread_should_stop;
@@ -396,6 +396,13 @@ void microtcp_process_packet(microtcp_t *mtcp, const void *packet, size_t len)
UNLOCK_WHEN_THREADED(mtcp);
}
static uint64_t get_time_in_ms(void)
{
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return t.tv_sec * 1000 + t.tv_nsec / 1000000;
}
void microtcp_step(microtcp_t *mtcp)
{
char packet[1024]; // This buffer is the bottleneck for the
@@ -408,18 +415,20 @@ void microtcp_step(microtcp_t *mtcp)
if (size < 0)
return;
uint64_t current_time_ms = get_time_in_ms();
fprintf(stderr, "current_time_ms=%lld\n", current_time_ms);
LOCK_WHEN_THREADED(mtcp);
{
process_packet(mtcp, packet, size);
time_t current_time = time(NULL);
int secs = (float) (current_time - mtcp->last_update_time);
uint64_t ms = (current_time_ms - mtcp->last_update_time_ms);
if (secs > 0) {
ip_seconds_passed(&mtcp->ip_state, secs);
arp_seconds_passed(&mtcp->arp_state, secs);
tcp_seconds_passed(&mtcp->tcp_state, secs);
mtcp->last_update_time = current_time;
if (ms > 0) {
ip_ms_passed(&mtcp->ip_state, ms);
arp_ms_passed(&mtcp->arp_state, ms);
tcp_ms_passed(&mtcp->tcp_state, ms);
mtcp->last_update_time_ms = current_time_ms;
}
}
UNLOCK_WHEN_THREADED(mtcp);
@@ -458,7 +467,7 @@ microtcp_t *microtcp_create_using_callbacks(const char *ip, const char *mac,
mtcp->ip = parsed_ip;
mtcp->mac = parsed_mac;
mtcp->callbacks = callbacks;
mtcp->last_update_time = time(NULL);
mtcp->last_update_time_ms = get_time_in_ms();
mtcp->used_buffer = NULL;
mtcp->wait_buffer_list = NULL;
+42 -8
View File
@@ -42,9 +42,9 @@ void tcp_free(tcp_state_t *state)
tcp_timerset_free(&state->timers);
}
void tcp_seconds_passed(tcp_state_t *state, size_t seconds)
void tcp_ms_passed(tcp_state_t *state, size_t ms)
{
tcp_timerset_step(&state->timers, seconds);
tcp_timerset_step(&state->timers, ms);
}
static tcp_connection_t*
@@ -74,6 +74,13 @@ connection_create(tcp_listener_t *listener,
connection->state = TCP_STATE_CLOSED;
connection->rtt = 0;
connection->dev_rtt = 0;
connection->calculating_rtt = false;
connection->rtt_calc_seq = 0;
connection->rtt_calc_time = 0;
connection->peer_port = peer_port;
connection->peer_ip = peer_ip;
@@ -110,7 +117,7 @@ find_listener_with_port(tcp_state_t *state, uint16_t port)
return NULL;
}
static uint32_t choose_sequence_no()
static uint32_t choose_sequence_no(void)
{
return 0;
}
@@ -222,6 +229,11 @@ static void emit_segment(tcp_connection_t *connection, uint8_t flags, size_t pay
}
}
if (!connection->calculating_rtt) {
connection->calculating_rtt = true;
connection->rtt_calc_seq = connection->snd_nxt; // -1?
connection->rtt_calc_time = connection->listener->state->timers.current_time_ms;
}
}
static void handle_received_data(tcp_connection_t *connection,
@@ -331,10 +343,30 @@ static bool ack_until(tcp_connection_t *connection, uint32_t ack_no)
}
size_t newly_acked_bytes = ack_no - connection->snd_una;
memmove(connection->out_buffer, connection->out_buffer + newly_acked_bytes, connection->snd_wnd - newly_acked_bytes);
connection->snd_wnd -= newly_acked_bytes;
if (ack_no > 1) { // Only remove data from the output buffer when
// the acked data wasn't a ghost byte
memmove(connection->out_buffer, connection->out_buffer + newly_acked_bytes, connection->snd_wnd - newly_acked_bytes);
connection->snd_wnd -= newly_acked_bytes;
}
connection->snd_una = ack_no;
TCP_DEBUG_LOG("calculating_rtt=%s, ack_no=%d, calc_seq=%d", connection->calculating_rtt ? "true" : "false", ack_no, connection->rtt_calc_seq);
if (connection->calculating_rtt) {
if (ack_no >= connection->rtt_calc_seq) {
uint64_t rtt = connection->listener->state->timers.current_time_ms - connection->rtt_calc_time;
TCP_DEBUG_LOG("Estimated RTT=%lld", rtt);
float w1 = 0.9;
float w2 = 0.125;
connection->rtt = w1 * rtt + (1-w1) * connection->rtt;
connection->dev_rtt = w2 * ABS((int) rtt - (int) connection->rtt) + (1-w2) * connection->dev_rtt;
connection->calculating_rtt = false;
}
}
return true;
}
@@ -519,6 +551,9 @@ void tcp_process_segment(tcp_state_t *state, ip_address_t sender,
TCP_DEBUG_LOG("Connection request handled");
} else {
TCP_DEBUG_LOG("RTT=%lld, DevRTT=%lld", connection->rtt, connection->dev_rtt);
// Something sent to an already instanciated
// connection. Since there is an instance, it
// means that at least the first SYN was received
@@ -560,7 +595,8 @@ void tcp_process_segment(tcp_state_t *state, ip_address_t sender,
"the peer will retransmit it");
// The connection is now established.
connection->snd_una = net_to_cpu_u32(segment->ack_no);
uint32_t ack_no = net_to_cpu_u32(segment->ack_no);
ack_until(connection, ack_no);
connection->state = TCP_STATE_ESTAB;
move_from_non_established_list_to_non_accepted_queue(connection);
@@ -747,8 +783,6 @@ tcp_connection_t *tcp_listener_accept(tcp_listener_t *listener, void *callback_d
void (*callback_ready_to_recv)(void*),
void (*callback_ready_to_send)(void*))
{
(void) listener;
if (!listener->non_accepted_queue_head)
// Nothing to accept
return NULL;
+9 -2
View File
@@ -6,7 +6,7 @@
#include "tcp_timer.h"
#endif
#define TCP_TIMEOUT_TIME_WAIT 240
#define TCP_TIMEOUT_TIME_WAIT 240000
#define TCP_MAX_TIMEOUTS 1024
#define TCP_MAX_LISTENERS 32
@@ -88,6 +88,13 @@ struct tcp_connection_t {
ip_address_t peer_ip; // Network byte order
uint16_t peer_port; // CPU byte order
uint64_t rtt;
uint64_t dev_rtt;
bool calculating_rtt;
uint32_t rtt_calc_seq;
uint64_t rtt_calc_time;
// Send Sequence Space
//
// 1 2 3 4
@@ -166,7 +173,7 @@ struct tcp_state_t {
void tcp_init(tcp_state_t *tcp_state, ip_address_t ip, tcp_callbacks_t callbacks);
void tcp_free(tcp_state_t *tcp_state);
void tcp_seconds_passed(tcp_state_t *state, size_t seconds);
void tcp_ms_passed(tcp_state_t *state, size_t ms);
void tcp_process_segment(tcp_state_t *state, ip_address_t sender, tcp_segment_t *segment, size_t len);
tcp_listener_t *tcp_listener_create(tcp_state_t *state, uint16_t port, bool reuse, void *data, void (*callback)(void*));
void tcp_listener_destroy(tcp_listener_t *listener);
+6 -6
View File
@@ -41,7 +41,7 @@ void tcp_timer_disable(tcp_timer_t *timer)
set->free_list = timer;
}
tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t seconds,
tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t ms,
void (*callback)(void*), void *data)
{
assert(callback);
@@ -58,7 +58,7 @@ tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t seconds,
// first item of the free list.
timer->set = set;
timer->deadline = set->current_time + seconds;
timer->deadline = set->current_time_ms + ms;
timer->data = data;
timer->callback = callback;
@@ -107,11 +107,11 @@ tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t seconds,
return timer;
}
void tcp_timerset_step(tcp_timerset_t *set, size_t seconds)
void tcp_timerset_step(tcp_timerset_t *set, size_t ms)
{
set->current_time += seconds;
set->current_time_ms += ms;
if (set->used_list == NULL || set->used_list->deadline > set->current_time)
if (set->used_list == NULL || set->used_list->deadline > set->current_time_ms)
// No timeouts triggered
return;
@@ -122,7 +122,7 @@ void tcp_timerset_step(tcp_timerset_t *set, size_t seconds)
tcp_timer_t *timeout = set->used_list;
while (timeout) {
if (timeout->deadline > set->current_time)
if (timeout->deadline > set->current_time_ms)
// This timeout didn't trigger, so the last
// timed out timeout was the previous one.
break;
+3 -3
View File
@@ -17,15 +17,15 @@ struct tcp_timer_t {
};
struct tcp_timerset_t {
uint64_t current_time;
uint64_t current_time_ms;
tcp_timer_t *used_list;
tcp_timer_t *free_list;
tcp_timer_t pool[TCP_MAX_TIMERS];
};
void tcp_timerset_step(tcp_timerset_t *set, size_t seconds);
void tcp_timerset_step(tcp_timerset_t *set, size_t ms);
void tcp_timerset_init(tcp_timerset_t *set);
void tcp_timerset_free(tcp_timerset_t *set);
void tcp_timer_disable(tcp_timer_t *timer);
tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t seconds,
tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t ms,
void (*callback)(void*), void *data);