diff --git a/projects/tlayer/main.c b/projects/tlayer/main.c index 5a98380e04..d68f07fd05 100644 --- a/projects/tlayer/main.c +++ b/projects/tlayer/main.c @@ -265,7 +265,7 @@ void send_tcp_bulk(char *str) void send_tcp_bandwidth_test(char *str) { timex_t start, end, total; - uint32_t secs; + double secs; int i = 0, count; char command[80]; @@ -280,10 +280,9 @@ void send_tcp_bandwidth_test(char *str) } end = vtimer_now(); total = timex_sub(end, start); - secs = total.microseconds / 1000000; + secs = total.microseconds / 1000000.0f; printf("Start: %lu, End: %lu, Total: %lu\n", start.microseconds, end.microseconds, total.microseconds); - secs = total.microseconds / 1000000; - printf("Time: %lu seconds, Bandwidth: %lu byte/second\n", secs, (count*48)/secs); + printf("Time: %f seconds, Bandwidth: %f byte/second\n", secs, (count*48)/secs); } void connect_tcp(char *str) diff --git a/sys/net/destiny/socket.c b/sys/net/destiny/socket.c index 7891874446..f9665ea92c 100644 --- a/sys/net/destiny/socket.c +++ b/sys/net/destiny/socket.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "udp.h" #include "tcp.h" #include "socket.h" @@ -216,6 +217,7 @@ int bind_tcp_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid) } memcpy(&getSocket(s)->socket_values.local_address, name, namelen); getSocket(s)->recv_pid = pid; + getSocket(s)->socket_values.tcp_control.rto = TCP_INITIAL_ACK_TIMEOUT; return 1; } @@ -587,6 +589,36 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen) return 0; } +void calculate_rto(tcp_cb_t *tcp_control, timex_t current_time) + { + double rtt = timex_sub(current_time, tcp_control->last_packet_time).microseconds; + double srtt = tcp_control->srtt; + double rttvar = tcp_control->rttvar; + double rto = tcp_control->rto; + + if ((srtt == 0) && (rttvar == 0) && (rto == TCP_INITIAL_ACK_TIMEOUT)) + { + // First calculation + srtt = rtt; + rttvar = 0.5*rtt; + rto = rtt + 4*rttvar; + } + else + { + // every other calculation + srtt = (1-TCP_ALPHA)*srtt+TCP_ALPHA*rtt; + rttvar = (1-TCP_BETA)*rttvar+TCP_BETA*abs(srtt-rtt); + rto = srtt + (((4*rttvar) < TCP_TIMER_RESOLUTION) ? (TCP_TIMER_RESOLUTION) : (4*rttvar)); + } + if (rto < SECOND) + { + rto = SECOND; + } + tcp_control->srtt = srtt; + tcp_control->rttvar = rttvar; + tcp_control->rto = rto; + } + int32_t send(int s, void *msg, uint64_t len, int flags) { // Variables @@ -690,6 +722,10 @@ int32_t send(int s, void *msg, uint64_t len, int flags) { case TCP_ACK: { + if (current_tcp_socket->tcp_control.no_of_retries == 0) + { + calculate_rto(¤t_tcp_socket->tcp_control, vtimer_now()); + } tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(recv_msg.content.ptr)); if ((current_tcp_socket->tcp_control.send_nxt == tcp_header->ack_nr) && (total_sent_bytes == len)) { diff --git a/sys/net/destiny/socket.h b/sys/net/destiny/socket.h index 42d74d196c..ec1ebabb97 100644 --- a/sys/net/destiny/socket.h +++ b/sys/net/destiny/socket.h @@ -158,6 +158,10 @@ typedef struct tcp_control_block uint8_t state; + double srtt; + double rttvar; + double rto; + #ifdef TCP_HC tcp_hc_context_t tcp_context; #endif diff --git a/sys/net/destiny/tcp_timer.c b/sys/net/destiny/tcp_timer.c index 2d29dc9cf7..418a2e885c 100644 --- a/sys/net/destiny/tcp_timer.c +++ b/sys/net/destiny/tcp_timer.c @@ -50,7 +50,7 @@ void handle_synchro_timeout(socket_internal_t *current_socket) void handle_established(socket_internal_t *current_socket) { msg_t send; - uint32_t current_timeout = TCP_ACK_TIMEOUT; + uint32_t current_timeout = (uint32_t)(current_socket->socket_values.tcp_control.rto); uint8_t i; if ((current_socket->socket_values.tcp_control.send_nxt > current_socket->socket_values.tcp_control.send_una) && (thread_getstatus(current_socket->send_pid) == STATUS_RECEIVE_BLOCKED)) @@ -130,7 +130,7 @@ void inc_global_variables(void) void tcp_general_timer(void) { vtimer_t tcp_vtimer; - timex_t interval = timex_set(0, 500*1000); + timex_t interval = timex_set(0, TCP_TIMER_RESOLUTION); while (1) { diff --git a/sys/net/destiny/tcp_timer.h b/sys/net/destiny/tcp_timer.h index f95abfb3de..13deaed92b 100644 --- a/sys/net/destiny/tcp_timer.h +++ b/sys/net/destiny/tcp_timer.h @@ -8,13 +8,18 @@ #ifndef TCP_TIMER_H_ #define TCP_TIMER_H_ -#define SECONDS 1000*1000 +#define TCP_TIMER_RESOLUTION 500*1000 + +#define SECOND 1000*1000 #define TCP_TIMER_STACKSIZE 2048 -#define TCP_SYN_INITIAL_TIMEOUT 6*SECONDS -#define TCP_SYN_TIMEOUT 24*SECONDS +#define TCP_SYN_INITIAL_TIMEOUT 6*SECOND +#define TCP_SYN_TIMEOUT 24*SECOND #define TCP_MAX_SYN_RETRIES 3 -#define TCP_ACK_TIMEOUT 3*SECONDS // still static, should be calculated via RTT -#define TCP_ACK_MAX_TIMEOUT 30*SECONDS // TODO: Set back to 90 Seconds +#define TCP_INITIAL_ACK_TIMEOUT 3*SECOND // still static, should be calculated via RTT +#define TCP_ACK_MAX_TIMEOUT 30*SECOND // TODO: Set back to 90 Seconds + +#define TCP_ALPHA 1.0f/8.0f +#define TCP_BETA 1.0f/4.0f #define TCP_NOT_DEFINED 0 #define TCP_RETRY 1