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:
parent
50a07d9874
commit
75546fcf6c
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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(¤t_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(¤t_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(¤t_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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user