|
@@ -314,6 +314,9 @@ void tcp_set_flags ( struct tcp_connection *conn ) {
|
314
|
314
|
if ( conn->tcp_lstate == TCP_CLOSE_WAIT ) {
|
315
|
315
|
conn->tcp_flags |= TCP_FIN;
|
316
|
316
|
}
|
|
317
|
+ if ( conn->tcp_lstate == TCP_ESTABLISHED ) {
|
|
318
|
+ conn->tcp_flags |= ( TCP_FIN | TCP_ACK );
|
|
319
|
+ }
|
317
|
320
|
break;
|
318
|
321
|
default:
|
319
|
322
|
DBG ( "TCP_INVALID state %d\n", conn->tcp_state );
|
|
@@ -909,10 +912,13 @@ static int tcp_rx ( struct pk_buff *pkb,
|
909
|
912
|
ntohl ( tcphdr->seq ), conn->rcv_nxt );
|
910
|
913
|
}
|
911
|
914
|
|
912
|
|
- /* Acknowledge new data */
|
913
|
|
- conn->tcp_flags |= TCP_ACK;
|
914
|
|
- if ( !( tcphdr->flags & TCP_ACK ) ) {
|
915
|
|
- goto send_tcp_nomsg;
|
|
915
|
+ /* Send an ACK only if required to */
|
|
916
|
+ if ( conn->rcv_nxt <= ntohl ( tcphdr->seq ) ) {
|
|
917
|
+ /* Acknowledge new data */
|
|
918
|
+ conn->tcp_flags |= TCP_ACK;
|
|
919
|
+ if ( !( tcphdr->flags & TCP_ACK ) ) {
|
|
920
|
+ goto send_tcp_nomsg;
|
|
921
|
+ }
|
916
|
922
|
}
|
917
|
923
|
}
|
918
|
924
|
|
|
@@ -934,8 +940,12 @@ static int tcp_rx ( struct pk_buff *pkb,
|
934
|
940
|
|
935
|
941
|
/* If the connection is in ESTABLISHED and it receives a FIN */
|
936
|
942
|
if ( conn->tcp_state == ESTABLISHED && ( tcphdr->flags & TCP_FIN ) ) {
|
|
943
|
+ if ( tcphdr->flags & TCP_ACK ) {
|
|
944
|
+ tcp_trans ( conn, TCP_LAST_ACK );
|
|
945
|
+ goto send_tcp_nomsg;
|
|
946
|
+ }
|
937
|
947
|
tcp_trans ( conn, TCP_CLOSE_WAIT );
|
938
|
|
- conn->tcp_op->closed ( conn, CONN_SNDCLOSE );
|
|
948
|
+// conn->tcp_op->closed ( conn, CONN_SNDCLOSE );
|
939
|
949
|
conn->rcv_nxt++;
|
940
|
950
|
if ( ! ( tcphdr->flags & TCP_ACK ) ) {
|
941
|
951
|
conn->tcp_flags |= TCP_ACK;
|