2012-01-24 03:19:11 +01:00
|
|
|
/*
|
|
|
|
* tcp_timer.c
|
|
|
|
*
|
|
|
|
* Created on: 21.01.2012
|
|
|
|
* Author: Oliver
|
|
|
|
*/
|
|
|
|
|
2012-02-14 21:28:51 +01:00
|
|
|
#include <thread.h>
|
2012-01-24 03:19:11 +01:00
|
|
|
#include <stdio.h>
|
2012-02-14 21:28:51 +01:00
|
|
|
#include <string.h>
|
2012-02-05 00:33:55 +01:00
|
|
|
#include <stdlib.h>
|
2012-02-14 21:28:51 +01:00
|
|
|
#include <math.h>
|
2012-01-24 03:19:11 +01:00
|
|
|
#include "tcp_timer.h"
|
|
|
|
#include "vtimer.h"
|
|
|
|
#include "thread.h"
|
|
|
|
#include "destiny.h"
|
|
|
|
#include "socket.h"
|
|
|
|
#include "net_help/msg_help.h"
|
2013-05-22 16:54:20 +02:00
|
|
|
#include "../sixlowpan/sixlowpan.h"
|
2012-01-24 03:19:11 +01:00
|
|
|
|
2012-01-27 02:54:59 +01:00
|
|
|
void handle_synchro_timeout(socket_internal_t *current_socket)
|
2012-01-24 03:19:11 +01:00
|
|
|
{
|
|
|
|
msg_t send;
|
2012-02-12 20:06:12 +01:00
|
|
|
if (thread_getstatus(current_socket->recv_pid) == STATUS_RECEIVE_BLOCKED)
|
2012-01-24 03:19:11 +01:00
|
|
|
{
|
2013-06-13 10:22:55 +02:00
|
|
|
timex_t now;
|
|
|
|
vtimer_now(&now);
|
2012-02-12 20:06:12 +01:00
|
|
|
if ((current_socket->socket_values.tcp_control.no_of_retries == 0) &&
|
2013-06-13 10:22:55 +02:00
|
|
|
(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds >
|
2012-02-12 20:06:12 +01:00
|
|
|
TCP_SYN_INITIAL_TIMEOUT))
|
2012-01-24 03:19:11 +01:00
|
|
|
{
|
2012-02-12 20:06:12 +01:00
|
|
|
current_socket->socket_values.tcp_control.no_of_retries++;
|
|
|
|
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
|
2012-03-01 02:48:22 +01:00
|
|
|
// printf("FIRST RETRY!\n");
|
2012-01-24 03:19:11 +01:00
|
|
|
}
|
2012-02-12 20:06:12 +01:00
|
|
|
else if ((current_socket->socket_values.tcp_control.no_of_retries > 0) &&
|
2013-06-13 10:22:55 +02:00
|
|
|
(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds >
|
2012-02-12 20:06:12 +01:00
|
|
|
(current_socket->socket_values.tcp_control.no_of_retries * TCP_SYN_TIMEOUT + TCP_SYN_INITIAL_TIMEOUT)))
|
2012-01-24 03:19:11 +01:00
|
|
|
{
|
2012-02-12 20:06:12 +01:00
|
|
|
current_socket->socket_values.tcp_control.no_of_retries++;
|
|
|
|
if (current_socket->socket_values.tcp_control.no_of_retries > TCP_MAX_SYN_RETRIES)
|
|
|
|
{
|
|
|
|
net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT);
|
2012-03-01 02:48:22 +01:00
|
|
|
// printf("TCP SYN TIMEOUT!!\n");
|
2012-02-12 20:06:12 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
|
2012-03-01 02:48:22 +01:00
|
|
|
// printf("NEXT RETRY!\n");
|
2012-02-12 20:06:12 +01:00
|
|
|
}
|
2012-01-24 03:19:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-27 02:54:59 +01:00
|
|
|
void handle_established(socket_internal_t *current_socket)
|
|
|
|
{
|
|
|
|
msg_t send;
|
2012-02-14 01:56:49 +01:00
|
|
|
double current_timeout = current_socket->socket_values.tcp_control.rto;
|
2012-02-14 21:28:51 +01:00
|
|
|
if (current_timeout < SECOND)
|
|
|
|
{
|
|
|
|
current_timeout = SECOND;
|
|
|
|
}
|
2012-01-27 02:54:59 +01:00
|
|
|
uint8_t i;
|
2012-02-12 04:26:55 +01:00
|
|
|
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))
|
2012-01-27 02:54:59 +01:00
|
|
|
{
|
2012-02-12 20:06:12 +01:00
|
|
|
for(i = 0; i < current_socket->socket_values.tcp_control.no_of_retries; i++)
|
2012-01-27 02:54:59 +01:00
|
|
|
{
|
|
|
|
current_timeout *= 2;
|
|
|
|
}
|
2013-06-13 10:22:55 +02:00
|
|
|
timex_t now;
|
|
|
|
vtimer_now(&now);
|
2012-01-27 02:54:59 +01:00
|
|
|
if (current_timeout > TCP_ACK_MAX_TIMEOUT)
|
|
|
|
{
|
|
|
|
net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT);
|
2012-03-01 02:48:22 +01:00
|
|
|
// printf("GOT NO ACK: TIMEOUT!\n");
|
2012-01-27 02:54:59 +01:00
|
|
|
}
|
2013-06-13 10:22:55 +02:00
|
|
|
else if (timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds >
|
2012-01-27 02:54:59 +01:00
|
|
|
current_timeout)
|
|
|
|
{
|
2012-03-01 02:48:22 +01:00
|
|
|
// printReasBuffers();
|
2012-02-12 20:06:12 +01:00
|
|
|
current_socket->socket_values.tcp_control.no_of_retries++;
|
2012-01-27 02:54:59 +01:00
|
|
|
net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY);
|
2012-03-01 02:48:22 +01:00
|
|
|
// printf("GOT NO ACK YET, %i. RETRY! Now: %lu Before: %lu, Diff: %lu, Cur Timeout: %f\n", current_socket->socket_values.tcp_control.no_of_retries,
|
2013-06-13 10:22:55 +02:00
|
|
|
// now.microseconds, current_socket->socket_values.tcp_control.last_packet_time.microseconds,
|
|
|
|
// now.microseconds - current_socket->socket_values.tcp_control.last_packet_time.microseconds,
|
2012-03-01 02:48:22 +01:00
|
|
|
// current_timeout);
|
2012-01-27 02:54:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-24 03:19:11 +01:00
|
|
|
void check_sockets(void)
|
|
|
|
{
|
|
|
|
socket_internal_t *current_socket;
|
|
|
|
uint8_t i = 1;
|
|
|
|
while (i < MAX_SOCKETS+1)
|
|
|
|
{
|
|
|
|
current_socket = getSocket(i);
|
|
|
|
|
|
|
|
if(isTCPSocket(i))
|
|
|
|
{
|
2012-01-25 03:38:22 +01:00
|
|
|
switch (current_socket->socket_values.tcp_control.state)
|
2012-01-24 03:19:11 +01:00
|
|
|
{
|
2012-01-27 02:54:59 +01:00
|
|
|
case ESTABLISHED:
|
|
|
|
{
|
|
|
|
handle_established(current_socket);
|
|
|
|
break;
|
|
|
|
}
|
2012-01-24 03:19:11 +01:00
|
|
|
case SYN_SENT:
|
|
|
|
{
|
2012-01-27 02:54:59 +01:00
|
|
|
handle_synchro_timeout(current_socket);
|
2012-01-24 03:19:11 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SYN_RCVD:
|
|
|
|
{
|
2012-01-27 02:54:59 +01:00
|
|
|
handle_synchro_timeout(current_socket);
|
2012-01-24 03:19:11 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-05 00:33:55 +01:00
|
|
|
void inc_global_variables(void)
|
|
|
|
{
|
|
|
|
mutex_lock(&global_sequence_clunter_mutex);
|
|
|
|
global_sequence_counter += rand();
|
|
|
|
mutex_unlock(&global_sequence_clunter_mutex, 0);
|
2012-02-07 04:24:00 +01:00
|
|
|
#ifdef TCP_HC
|
2012-02-05 00:33:55 +01:00
|
|
|
mutex_lock(&global_context_counter_mutex);
|
|
|
|
global_context_counter += rand();
|
|
|
|
mutex_unlock(&global_context_counter_mutex, 0);
|
2012-02-07 04:24:00 +01:00
|
|
|
#endif
|
2012-02-05 00:33:55 +01:00
|
|
|
}
|
|
|
|
|
2012-01-24 03:19:11 +01:00
|
|
|
void tcp_general_timer(void)
|
|
|
|
{
|
|
|
|
vtimer_t tcp_vtimer;
|
2012-02-14 01:37:06 +01:00
|
|
|
timex_t interval = timex_set(0, TCP_TIMER_RESOLUTION);
|
2012-01-24 03:19:11 +01:00
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
2012-02-05 00:33:55 +01:00
|
|
|
inc_global_variables();
|
2012-01-24 03:19:11 +01:00
|
|
|
check_sockets();
|
2012-02-01 21:07:57 +01:00
|
|
|
vtimer_set_wakeup(&tcp_vtimer, interval, thread_getpid());
|
2012-01-24 03:19:11 +01:00
|
|
|
thread_sleep();
|
|
|
|
}
|
|
|
|
}
|