TCP bug fix, TCP refactoring
This commit is contained in:
parent
7d1f607f0f
commit
6b84ae0807
@ -13,6 +13,38 @@
|
|||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "sys/net/net_help/net_help.h"
|
#include "sys/net/net_help/net_help.h"
|
||||||
|
|
||||||
|
void print_tcp_flags (tcp_hdr_t *tcp_header)
|
||||||
|
{
|
||||||
|
printf("FLAGS: ");
|
||||||
|
if ((tcp_header->reserved_flags & TCP_ACK) > 0)
|
||||||
|
{
|
||||||
|
printf("ACK ");
|
||||||
|
}
|
||||||
|
if ((tcp_header->reserved_flags & TCP_RST) > 0)
|
||||||
|
{
|
||||||
|
printf("RST ");
|
||||||
|
}
|
||||||
|
if ((tcp_header->reserved_flags & TCP_SYN) > 0)
|
||||||
|
{
|
||||||
|
printf("SYN ");
|
||||||
|
}
|
||||||
|
if ((tcp_header->reserved_flags & TCP_FIN) > 0)
|
||||||
|
{
|
||||||
|
printf("FIN ");
|
||||||
|
}
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header)
|
||||||
|
{
|
||||||
|
printf("--- %s TCP packet: ---\n", (in_or_out == INC_PACKET ? "Incoming" : "Outgoing"));
|
||||||
|
ipv6_print_addr(&ipv6_header->srcaddr);
|
||||||
|
ipv6_print_addr(&ipv6_header->destaddr);
|
||||||
|
printf("Source Port: %i, Dest. Port: %i\n", tcp_header->src_port, tcp_header->dst_port);
|
||||||
|
printf("ACK: %li, SEQ: %li, Window: %i\n", tcp_header->ack_nr, tcp_header->seq_nr, tcp_header->window);
|
||||||
|
print_tcp_flags(tcp_header);
|
||||||
|
}
|
||||||
|
|
||||||
void print_socket(uint8_t socket)
|
void print_socket(uint8_t socket)
|
||||||
{
|
{
|
||||||
socket_internal_t *current_socket_internal = &sockets[socket - 1];
|
socket_internal_t *current_socket_internal = &sockets[socket - 1];
|
||||||
@ -271,6 +303,26 @@ void set_tcp_packet(tcp_hdr_t *tcp_hdr, uint16_t src_port, uint16_t dst_port, ui
|
|||||||
tcp_hdr->window = window;
|
tcp_hdr->window = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for consistent ACK and SEQ number
|
||||||
|
// TODO: Use error codes for different kinds of inconsistency when needed!
|
||||||
|
int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header)
|
||||||
|
{
|
||||||
|
if (IS_TCP_ACK(tcp_header->reserved_flags))
|
||||||
|
{
|
||||||
|
if(tcp_header->ack_nr != (current_tcp_socket->local_tcp_status.seq_nr+1))
|
||||||
|
{
|
||||||
|
// TODO: possible loss of a packet (MAYBE!)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tcp_header->seq_nr <= current_tcp_socket->foreign_tcp_status.seq_nr)
|
||||||
|
{
|
||||||
|
// TODO: possible repetition of a packet or wrong order of arriving
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int connect(int socket, sockaddr6_t *addr, uint32_t addrlen, uint8_t tcp_client_thread)
|
int connect(int socket, sockaddr6_t *addr, uint32_t addrlen, uint8_t tcp_client_thread)
|
||||||
{
|
{
|
||||||
// Variables
|
// Variables
|
||||||
@ -310,8 +362,6 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen, uint8_t tcp_client_
|
|||||||
// Fill TCP SYN packet
|
// Fill TCP SYN packet
|
||||||
set_tcp_packet(current_tcp_packet, current_tcp_socket->local_address.sin6_port, current_tcp_socket->foreign_address.sin6_port,
|
set_tcp_packet(current_tcp_packet, current_tcp_socket->local_address.sin6_port, current_tcp_socket->foreign_address.sin6_port,
|
||||||
current_tcp_socket->local_tcp_status.seq_nr, 0, 0, TCP_SYN, current_tcp_socket->local_tcp_status.window, 0, 0);
|
current_tcp_socket->local_tcp_status.seq_nr, 0, 0, TCP_SYN, current_tcp_socket->local_tcp_status.window, 0, 0);
|
||||||
printf("PORT orig: %i, PORT socket: %i\n", addr->sin6_port, current_tcp_socket->foreign_address.sin6_port);
|
|
||||||
printTCPHeader(current_tcp_packet);
|
|
||||||
// Fill IPv6 Header
|
// Fill IPv6 Header
|
||||||
memcpy(&(temp_ipv6_header->destaddr), ¤t_tcp_socket->foreign_address.sin6_addr, 16);
|
memcpy(&(temp_ipv6_header->destaddr), ¤t_tcp_socket->foreign_address.sin6_addr, 16);
|
||||||
memcpy(&(temp_ipv6_header->srcaddr), ¤t_tcp_socket->local_address.sin6_addr, 16);
|
memcpy(&(temp_ipv6_header->srcaddr), ¤t_tcp_socket->local_address.sin6_addr, 16);
|
||||||
@ -326,7 +376,13 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen, uint8_t tcp_client_
|
|||||||
msg_receive(&msg_from_server);
|
msg_receive(&msg_from_server);
|
||||||
|
|
||||||
// Read packet content
|
// Read packet content
|
||||||
tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(msg_from_server.content.ptr+IPV6_HDR_LEN));
|
tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(buffer_tcp+IPV6_HDR_LEN));
|
||||||
|
|
||||||
|
// Check for consistency
|
||||||
|
if (check_tcp_consistency(current_tcp_socket, tcp_header) == -1)
|
||||||
|
{
|
||||||
|
printf("TCP packets not consistent!\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Got SYN ACK from Server
|
// Got SYN ACK from Server
|
||||||
// Refresh foreign TCP socket information
|
// Refresh foreign TCP socket information
|
||||||
@ -584,8 +640,14 @@ int handle_new_tcp_connection(socket_t *current_queued_socket, socket_internal_t
|
|||||||
ipv6_hdr_t *ipv6_header;
|
ipv6_hdr_t *ipv6_header;
|
||||||
tcp_hdr_t *tcp_header;
|
tcp_hdr_t *tcp_header;
|
||||||
|
|
||||||
ipv6_header = ((ipv6_hdr_t*)(msg_recv_client_ack.content.ptr));
|
ipv6_header = ((ipv6_hdr_t*)(buffer_tcp));
|
||||||
tcp_header = ((tcp_hdr_t*)(msg_recv_client_ack.content.ptr));
|
tcp_header = ((tcp_hdr_t*)(buffer_tcp+IPV6_HDR_LEN));
|
||||||
|
|
||||||
|
// Check for consistency
|
||||||
|
if (check_tcp_consistency(current_queued_socket, tcp_header) == -1)
|
||||||
|
{
|
||||||
|
printf("TCP packets not consistent!\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Got ack, connection established, refresh local and foreign tcp socket status
|
// Got ack, connection established, refresh local and foreign tcp socket status
|
||||||
set_tcp_status(¤t_queued_socket->foreign_tcp_status, tcp_header->ack_nr, STATIC_MSS, tcp_header->seq_nr, ESTABLISHED, tcp_header->window);
|
set_tcp_status(¤t_queued_socket->foreign_tcp_status, tcp_header->ack_nr, STATIC_MSS, tcp_header->seq_nr, ESTABLISHED, tcp_header->window);
|
||||||
|
|||||||
@ -113,6 +113,9 @@
|
|||||||
#define STATIC_MSS 32
|
#define STATIC_MSS 32
|
||||||
#define STATIC_WINDOW 32
|
#define STATIC_WINDOW 32
|
||||||
|
|
||||||
|
#define INC_PACKET 0
|
||||||
|
#define OUT_PACKET 1
|
||||||
|
|
||||||
typedef struct __attribute__ ((packed)) socka6
|
typedef struct __attribute__ ((packed)) socka6
|
||||||
{
|
{
|
||||||
uint8_t sin6_family; /* AF_INET6 */
|
uint8_t sin6_family; /* AF_INET6 */
|
||||||
@ -161,5 +164,6 @@ void print_sockets(void);
|
|||||||
void print_socket(uint8_t socket);
|
void print_socket(uint8_t socket);
|
||||||
bool exists_socket(uint8_t socket);
|
bool exists_socket(uint8_t socket);
|
||||||
socket_t *new_tcp_queued_socket(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *socket);
|
socket_t *new_tcp_queued_socket(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *socket);
|
||||||
|
void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header);
|
||||||
|
|
||||||
#endif /* SOCKET_H_ */
|
#endif /* SOCKET_H_ */
|
||||||
|
|||||||
@ -51,9 +51,69 @@ uint16_t tcp_csum(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header)
|
|||||||
return (sum == 0) ? 0xffff : HTONS(sum);
|
return (sum == 0) ? 0xffff : HTONS(sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket)
|
||||||
|
{
|
||||||
|
msg_t m_recv_tcp, m_send_tcp;
|
||||||
|
if (getWaitingConnectionSocket(tcp_socket->socket_id)->local_tcp_status.state == SYN_RCVD)
|
||||||
|
{
|
||||||
|
msg_send_receive(&m_send_tcp, &m_recv_tcp, tcp_socket->pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_tcp_rst_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_tcp_syn_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket)
|
||||||
|
{
|
||||||
|
msg_t m_send_tcp;
|
||||||
|
if (tcp_socket->in_socket.local_tcp_status.state == LISTEN)
|
||||||
|
{
|
||||||
|
socket_t *new_socket = new_tcp_queued_socket(ipv6_header, tcp_header, tcp_socket);
|
||||||
|
if (new_socket != NULL)
|
||||||
|
{
|
||||||
|
// notify socket function accept(..) that a new connection request has arrived
|
||||||
|
// No need to wait for an answer because the server accept() function isnt reading from anything other than the queued sockets
|
||||||
|
msg_send(&m_send_tcp, tcp_socket->pid, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Dropped TCP SYN Message because an error occured while requesting a new queued socket!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Droppec TCP SYN Message because socket was not in state LISTEN!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_tcp_syn_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket)
|
||||||
|
{
|
||||||
|
msg_t m_recv_tcp, m_send_tcp;
|
||||||
|
if (tcp_socket->in_socket.local_tcp_status.state == SYN_SENT)
|
||||||
|
{
|
||||||
|
msg_send_receive(&m_send_tcp, &m_recv_tcp, tcp_socket->pid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Socket not in state SYN_SENT, dropping SYN-ACK-packet!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_tcp_fin_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_tcp_fin_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void tcp_packet_handler (void)
|
void tcp_packet_handler (void)
|
||||||
{
|
{
|
||||||
msg_t m_recv_ip, m_send_ip, m_recv_tcp, m_send_tcp;
|
msg_t m_recv_ip, m_send_ip;
|
||||||
ipv6_hdr_t *ipv6_header;
|
ipv6_hdr_t *ipv6_header;
|
||||||
tcp_hdr_t *tcp_header;
|
tcp_hdr_t *tcp_header;
|
||||||
uint8_t *payload;
|
uint8_t *payload;
|
||||||
@ -66,12 +126,14 @@ void tcp_packet_handler (void)
|
|||||||
ipv6_header = ((ipv6_hdr_t*)&buffer_tcp);
|
ipv6_header = ((ipv6_hdr_t*)&buffer_tcp);
|
||||||
tcp_header = ((tcp_hdr_t*)(&buffer_tcp[IPV6_HDR_LEN]));
|
tcp_header = ((tcp_hdr_t*)(&buffer_tcp[IPV6_HDR_LEN]));
|
||||||
payload = &buffer_tcp[IPV6_HDR_LEN+TCP_HDR_LEN];
|
payload = &buffer_tcp[IPV6_HDR_LEN+TCP_HDR_LEN];
|
||||||
printTCPHeader(tcp_header);
|
//printTCPHeader(tcp_header);
|
||||||
chksum = tcp_csum(ipv6_header, tcp_header);
|
chksum = tcp_csum(ipv6_header, tcp_header);
|
||||||
printf("Checksum is %x!\n", chksum);
|
printf("Checksum is %x!\n", chksum);
|
||||||
|
|
||||||
tcp_socket = get_tcp_socket(ipv6_header, tcp_header);
|
tcp_socket = get_tcp_socket(ipv6_header, tcp_header);
|
||||||
|
|
||||||
|
print_tcp_status(INC_PACKET, ipv6_header, tcp_header);
|
||||||
|
|
||||||
if ((chksum == 0xffff) && (tcp_socket != NULL))
|
if ((chksum == 0xffff) && (tcp_socket != NULL))
|
||||||
{
|
{
|
||||||
// Remove reserved bits from tcp flags field
|
// Remove reserved bits from tcp flags field
|
||||||
@ -83,69 +145,41 @@ void tcp_packet_handler (void)
|
|||||||
case TCP_ACK:
|
case TCP_ACK:
|
||||||
{
|
{
|
||||||
// only ACK Bit set
|
// only ACK Bit set
|
||||||
if (getWaitingConnectionSocket(tcp_socket->socket_id)->local_tcp_status.state == SYN_RCVD)
|
handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket);
|
||||||
{
|
|
||||||
m_send_tcp.content.ptr = (char*)buffer;
|
|
||||||
m_send_tcp.content.value = IPV6_HDR_LEN + ipv6_header->length;
|
|
||||||
msg_send_receive(&m_recv_tcp, &m_send_tcp, tcp_socket->pid);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TCP_RST:
|
case TCP_RST:
|
||||||
{
|
{
|
||||||
printf("RST Bit set!\n");
|
printf("RST Bit set!\n");
|
||||||
// only RST Bit set
|
// only RST Bit set
|
||||||
|
handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TCP_SYN:
|
case TCP_SYN:
|
||||||
{
|
{
|
||||||
// only SYN Bit set, look for matching, listening socket and request new queued socket
|
// only SYN Bit set, look for matching, listening socket and request new queued socket
|
||||||
printf("SYN Bit set!\n");
|
printf("SYN Bit set!\n");
|
||||||
if (tcp_socket->in_socket.local_tcp_status.state == LISTEN)
|
handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket);
|
||||||
{
|
|
||||||
socket_t *new_socket = new_tcp_queued_socket(ipv6_header, tcp_header, tcp_socket);
|
|
||||||
if (new_socket != NULL)
|
|
||||||
{
|
|
||||||
// notify socket function accept(..) that a new connection request has arrived
|
|
||||||
// No need to wait for an answer because the server accept() function isnt reading from anything other than the queued sockets
|
|
||||||
msg_send(&m_send_tcp, tcp_socket->pid, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Dropped TCP SYN Message because an error occured while requesting a new queued socket!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Droppec TCP SYN Message because socket was not in state LISTEN!");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TCP_SYN_ACK:
|
case TCP_SYN_ACK:
|
||||||
{
|
{
|
||||||
// only SYN and ACK Bit set, complete three way handshake when socket in state SYN_SENT
|
// only SYN and ACK Bit set, complete three way handshake when socket in state SYN_SENT
|
||||||
if (tcp_socket->in_socket.local_tcp_status.state == SYN_SENT)
|
handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket);
|
||||||
{
|
|
||||||
m_send_tcp.content.ptr = (char*)buffer;
|
|
||||||
m_send_tcp.content.value = IPV6_HDR_LEN + ipv6_header->length;
|
|
||||||
msg_send_receive(&m_recv_tcp, &m_send_tcp, tcp_socket->pid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Socket not in state SYN_SENT, dropping SYN-ACK-packet!");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TCP_FIN:
|
case TCP_FIN:
|
||||||
{
|
{
|
||||||
printf("FIN Bit set!\n");
|
printf("FIN Bit set!\n");
|
||||||
// only FIN Bit set
|
// only FIN Bit set
|
||||||
|
handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TCP_FIN_ACK:
|
case TCP_FIN_ACK:
|
||||||
{
|
{
|
||||||
printf("FIN ACK Bit set!\n");
|
printf("FIN ACK Bit set!\n");
|
||||||
// only FIN and ACK Bit set
|
// only FIN and ACK Bit set
|
||||||
|
handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user