aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2021-02-22 10:58:46 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2021-02-22 16:13:58 +0000
commit9febbc4541903bb8e6b0f1c84988c98b2f7c96ef (patch)
tree39dcefb29aa0ebcc7d947651d202cd1fd14517b0
parent808d4aad1022a2a33d222663b0c9badde30b9d45 (diff)
downloadsrc-9febbc4541903bb8e6b0f1c84988c98b2f7c96ef.tar.gz
src-9febbc4541903bb8e6b0f1c84988c98b2f7c96ef.zip
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@incore.de> PR: 230755 MFC after: 1 week Sponsored by: Mellanox Technologies // NVIDIA Networking
-rw-r--r--sys/netinet/libalias/alias_db.c16
1 files 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;