1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2026-01-01 01:41:18 +01:00

destiny: set ack bit for (almost) all segments after syn

The current implementation does not set the ack bit
for outgoing data segments and the fin segment.

However, RFC793 states that all segments
should have an ack bit set in order to present a valid
ack nr. in outgoing segments.

Currently, data segments and acknowledgement segments
are distinguished by the existence of their ack bit.
With the new assumption, that both of these types of
segments need an ack bit set, I had to change several
parts of the current implementation to make this
decision by inspecting the payload size.

destiny: added parens
This commit is contained in:
Cenk Gündoğan 2014-06-12 12:57:22 +02:00
parent 50a07d9874
commit 75546fcf6c
3 changed files with 52 additions and 46 deletions

View File

@ -406,9 +406,9 @@ void set_tcp_packet(tcp_hdr_t *tcp_hdr, uint16_t src_port, uint16_t dst_port,
}
/* Check for consistent ACK and SEQ number */
int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header)
int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header, uint8_t tcp_payload_len)
{
if (IS_TCP_ACK(tcp_header->reserved_flags)) {
if (tcp_payload_len == 0) {
if (tcp_header->ack_nr > (current_tcp_socket->tcp_control.send_nxt)) {
/* ACK of not yet sent byte, discard */
return ACK_NO_TOO_BIG;
@ -796,7 +796,7 @@ int32_t destiny_socket_send(int s, const void *buf, uint32_t len, int flags)
current_tcp_socket->tcp_control.send_wnd -= sent_bytes;
if (send_tcp(current_int_tcp_socket, current_tcp_packet,
temp_ipv6_header, 0, sent_bytes) < 0) {
temp_ipv6_header, TCP_ACK, sent_bytes) < 0) {
/* Error while sending tcp data */
current_tcp_socket->tcp_control.send_nxt -= sent_bytes;
current_tcp_socket->tcp_control.send_wnd += sent_bytes;
@ -1063,7 +1063,6 @@ int destiny_socket_close(int s)
current_socket->send_pid = thread_getpid();
/* Refresh local TCP socket information */
current_socket->socket_values.tcp_control.send_una++;
current_socket->socket_values.tcp_control.state = TCP_FIN_WAIT_1;
#ifdef TCP_HC
current_socket->socket_values.tcp_control.tcp_context.hc_type =
@ -1071,7 +1070,7 @@ int destiny_socket_close(int s)
#endif
send_tcp(current_socket, current_tcp_packet, temp_ipv6_header,
TCP_FIN, 0);
TCP_FIN_ACK, 0);
msg_receive(&m_recv);
close_socket(current_socket);
return 1;

View File

@ -85,7 +85,7 @@ void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header,
tcp_hdr_t *tcp_header, socket_t *tcp_socket);
void set_tcp_cb(tcp_cb_t *tcp_control, uint32_t rcv_nxt, uint16_t rcv_wnd,
uint32_t send_nxt, uint32_t send_una, uint16_t send_wnd);
int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header);
int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header, uint8_t tcp_payload_len);
void switch_tcp_packet_byte_order(tcp_hdr_t *current_tcp_packet);
int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet,
ipv6_hdr_t *temp_ipv6_header, uint8_t flags,

View File

@ -142,7 +142,7 @@ void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
return;
}
else if (tcp_socket->socket_values.tcp_control.state == TCP_ESTABLISHED) {
if (check_tcp_consistency(&tcp_socket->socket_values, tcp_header) == PACKET_OK) {
if (check_tcp_consistency(&tcp_socket->socket_values, tcp_header, 0) == PACKET_OK) {
m_send_tcp.content.ptr = (char *)tcp_header;
net_msg_send(&m_send_tcp, tcp_socket->send_pid, 0, TCP_ACK);
return;
@ -219,7 +219,7 @@ void handle_tcp_fin_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN]));
set_tcp_cb(&current_tcp_socket->tcp_control, tcp_header->seq_nr + 1,
current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr,
current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr + 1,
tcp_header->ack_nr, tcp_header->window);
#ifdef TCP_HC
@ -268,44 +268,41 @@ void handle_tcp_fin_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
}
void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket, uint8_t *payload)
socket_internal_t *tcp_socket, uint8_t *payload, uint8_t tcp_payload_len)
{
uint8_t tcp_payload_len = NTOHS(ipv6_header->length) - TCP_HDR_LEN, read_bytes = 0;
uint8_t read_bytes = 0;
socket_t *current_tcp_socket = &tcp_socket->socket_values;
uint8_t send_buffer[BUFFER_SIZE];
ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer));
tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN]));
if (tcp_payload_len > 0) {
if (check_tcp_consistency(current_tcp_socket, tcp_header, tcp_payload_len) == PACKET_OK) {
read_bytes = handle_payload(ipv6_header, tcp_header, tcp_socket, payload);
if (check_tcp_consistency(current_tcp_socket, tcp_header) == PACKET_OK) {
read_bytes = handle_payload(ipv6_header, tcp_header, tcp_socket, payload);
/* Refresh TCP status values */
current_tcp_socket->tcp_control.state = TCP_ESTABLISHED;
/* Refresh TCP status values */
current_tcp_socket->tcp_control.state = TCP_ESTABLISHED;
set_tcp_cb(&current_tcp_socket->tcp_control,
tcp_header->seq_nr + read_bytes,
current_tcp_socket->tcp_control.rcv_wnd,
current_tcp_socket->tcp_control.send_nxt,
current_tcp_socket->tcp_control.send_una,
current_tcp_socket->tcp_control.send_wnd);
set_tcp_cb(&current_tcp_socket->tcp_control,
tcp_header->seq_nr + read_bytes,
current_tcp_socket->tcp_control.rcv_wnd,
current_tcp_socket->tcp_control.send_nxt,
current_tcp_socket->tcp_control.send_una,
current_tcp_socket->tcp_control.send_wnd);
/* Send packet */
// block_continue_thread();
/* Send packet */
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
}
/* ACK packet probably got lost */
else {
// block_continue_thread();
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
}
/* ACK packet probably got lost */
else {
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
#endif
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
}
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
}
}
@ -344,7 +341,19 @@ void tcp_packet_handler(void)
switch (tcp_flags) {
case TCP_ACK: {
/* only ACK Bit set */
handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket);
uint8_t tcp_payload_len = NTOHS(ipv6_header->length) - TCP_HDR_LEN;
uint8_t state = tcp_socket->socket_values.tcp_control.state;
if ((tcp_payload_len > 0) && (state == TCP_ESTABLISHED)) {
/* handle data segments only when the connection was established successfully */
handle_tcp_no_flags_packet(ipv6_header, tcp_header, tcp_socket, payload, tcp_payload_len);
}
else if (tcp_payload_len == 0
&& (state == TCP_ESTABLISHED || state == TCP_SYN_RCVD
|| state == TCP_CLOSING || state == TCP_LAST_ACK)) {
/* no payload, acknowledging data only */
handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket);
}
break;
}
@ -370,23 +379,21 @@ void tcp_packet_handler(void)
break;
}
case TCP_FIN: {
printf("FIN Bit set!\n");
/* only FIN Bit set */
handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket);
break;
}
case TCP_FIN_ACK: {
printf("FIN ACK Bit set!\n");
/* only FIN and ACK Bit set */
handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket);
if (tcp_socket->socket_values.tcp_control.state == TCP_ESTABLISHED) {
/* this is the first FIN */
printf("FIN ACK Bit set!\n");
handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket);
}
else {
/* this is the response to FIN */
handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket);
}
break;
}
default: {
handle_tcp_no_flags_packet(ipv6_header, tcp_header,
tcp_socket, payload);
printf("Unable to process the incoming segment!\n");
}
}
}