Merge pull request #1321 from cgundogan/fix_missing_ack_bit

destiny: set ack bit for (almost) all segments after syn
dev/timer
Oleg Hahm 9 years ago
commit fda7ce12d2

@ -408,9 +408,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;
@ -798,7 +798,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;
@ -1065,7 +1065,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 =
@ -1073,7 +1072,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(&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) == PACKET_OK) {
read_bytes = handle_payload(ipv6_header, tcp_header, tcp_socket, payload);
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);
/* 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);
}
}
@ -343,7 +340,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;
}
@ -369,23 +378,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…
Cancel
Save