git: 9febbc454190 - main - Fix for natd(8) sending wrong sequence number after TCP retransmission, terminating a TCP connection.

Hans Petter Selasky hselasky at FreeBSD.org
Mon Feb 22 16:15:24 UTC 2021


The branch main has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=9febbc4541903bb8e6b0f1c84988c98b2f7c96ef

commit 9febbc4541903bb8e6b0f1c84988c98b2f7c96ef
Author:     Hans Petter Selasky <hselasky at FreeBSD.org>
AuthorDate: 2021-02-22 10:58:46 +0000
Commit:     Hans Petter Selasky <hselasky at FreeBSD.org>
CommitDate: 2021-02-22 16:13:58 +0000

    Fix for natd(8) sending wrong sequence number after TCP retransmission,
    terminating a TCP connection.
    
    If a TCP packet must be retransmitted and the data length has changed in the
    retransmitted packet, due to the internal workings of TCP, typically when ACK
    packets are lost, then there is a 30% chance that the logic in GetDeltaSeqOut()
    will find the correct length, which is the last length received.
    
    This can be explained as follows:
    
    If a "227 Entering Passive Mode" packet must be retransmittet and the length
    changes from 51 to 50 bytes, for example, then we have three cases for the
    list scan in GetDeltaSeqOut(), depending on how many prior packets were
    received modulus N_LINK_TCP_DATA=3:
    
      case 1:  index 0:   original packet        51
               index 1:   retransmitted packet   50
               index 2:   not relevant
    
      case 2:  index 0:   not relevant
               index 1:   original packet        51
               index 2:   retransmitted packet   50
    
      case 3:  index 0:   retransmitted packet   50
               index 1:   not relevant
               index 2:   original packet        51
    
    This patch simply changes the searching order for TCP packets, always starting
    at the last received packet instead of any received packet, in
    GetDeltaAckIn() and GetDeltaSeqOut().
    
    Else no functional changes.
    
    Discussed with: rscheff@
    Submitted by:   Andreas Longwitz <longwitz at incore.de>
    PR:             230755
    MFC after:      1 week
    Sponsored by:   Mellanox Technologies // NVIDIA Networking
---
 sys/netinet/libalias/alias_db.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index 1f85a606b2d5..c87273c863ca 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -1937,14 +1937,18 @@ TCP packet.  To do this, a circular list of ACK numbers where the TCP
 packet size was altered is searched.
 */
 
-	int i;
+	int i, j;
 	int delta, ack_diff_min;
 
 	delta = 0;
 	ack_diff_min = -1;
-	for (i = 0; i < N_LINK_TCP_DATA; i++) {
+	i = lnk->data.tcp->state.index;
+	for (j = 0; j < N_LINK_TCP_DATA; j++) {
 		struct ack_data_record x;
 
+		if (i == 0)
+			i = N_LINK_TCP_DATA;
+		i--;
 		x = lnk->data.tcp->ack[i];
 		if (x.active == 1) {
 			int ack_diff;
@@ -1976,14 +1980,18 @@ TCP packet.  To do this, a circular list of ACK numbers where the TCP
 packet size was altered is searched.
 */
 
-	int i;
+	int i, j;
 	int delta, seq_diff_min;
 
 	delta = 0;
 	seq_diff_min = -1;
-	for (i = 0; i < N_LINK_TCP_DATA; i++) {
+	i = lnk->data.tcp->state.index;
+	for (j = 0; j < N_LINK_TCP_DATA; j++) {
 		struct ack_data_record x;
 
+		if (i == 0)
+			i = N_LINK_TCP_DATA;
+		i--;
 		x = lnk->data.tcp->ack[i];
 		if (x.active == 1) {
 			int seq_diff;


More information about the dev-commits-src-all mailing list