1195972f6Sopenharmony_ciFrom 08716b71ccb93c6d998d1654c1fac137f29d2851 Mon Sep 17 00:00:00 2001
2195972f6Sopenharmony_ciFrom: wuchangsheng <wuchangsheng2@huawei.com>
3195972f6Sopenharmony_ciDate: Tue, 13 Dec 2022 22:27:33 +0800
4195972f6Sopenharmony_ciSubject: [PATCH] optimite pcb-list limit , send size and ack now
5195972f6Sopenharmony_ci
6195972f6Sopenharmony_ci---
7195972f6Sopenharmony_ci src/core/tcp.c         |   1 +
8195972f6Sopenharmony_ci src/core/tcp_in.c      |  16 +++++++-
9195972f6Sopenharmony_ci src/core/tcp_out.c     | 103 ++++++++++++++++++++++++++++++-------------------
10195972f6Sopenharmony_ci src/include/lwip/opt.h |   2 +-
11195972f6Sopenharmony_ci src/include/lwip/tcp.h |   2 +
12195972f6Sopenharmony_ci src/include/lwipsock.h |   2 -
13195972f6Sopenharmony_ci 6 files changed, 83 insertions(+), 43 deletions(-)
14195972f6Sopenharmony_ci
15195972f6Sopenharmony_cidiff --git a/src/core/tcp.c b/src/core/tcp.c
16195972f6Sopenharmony_ciindex 51ada38..cb08f95 100644
17195972f6Sopenharmony_ci--- a/src/core/tcp.c
18195972f6Sopenharmony_ci+++ b/src/core/tcp.c
19195972f6Sopenharmony_ci@@ -2297,6 +2297,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
20195972f6Sopenharmony_ci     tcp_segs_free(pcb->unsent);
21195972f6Sopenharmony_ci     tcp_segs_free(pcb->unacked);
22195972f6Sopenharmony_ci     pcb->unacked = pcb->unsent = NULL;
23195972f6Sopenharmony_ci+    pcb->last_unacked = pcb->last_unsent = NULL;
24195972f6Sopenharmony_ci #if TCP_OVERSIZE
25195972f6Sopenharmony_ci     pcb->unsent_oversize = 0;
26195972f6Sopenharmony_ci #endif /* TCP_OVERSIZE */
27195972f6Sopenharmony_cidiff --git a/src/core/tcp_in.c b/src/core/tcp_in.c
28195972f6Sopenharmony_ciindex 2d6cb6a..78954bd 100644
29195972f6Sopenharmony_ci--- a/src/core/tcp_in.c
30195972f6Sopenharmony_ci+++ b/src/core/tcp_in.c
31195972f6Sopenharmony_ci@@ -976,8 +976,14 @@ tcp_process(struct tcp_pcb *pcb)
32195972f6Sopenharmony_ci           rseg = pcb->unsent;
33195972f6Sopenharmony_ci           LWIP_ASSERT("no segment to free", rseg != NULL);
34195972f6Sopenharmony_ci           pcb->unsent = rseg->next;
35195972f6Sopenharmony_ci+          if (pcb->last_unsent == rseg) {
36195972f6Sopenharmony_ci+            pcb->last_unsent = rseg->next;
37195972f6Sopenharmony_ci+          }
38195972f6Sopenharmony_ci         } else {
39195972f6Sopenharmony_ci           pcb->unacked = rseg->next;
40195972f6Sopenharmony_ci+          if (pcb->last_unacked == rseg) {
41195972f6Sopenharmony_ci+            pcb->last_unacked = rseg->next;
42195972f6Sopenharmony_ci+          }
43195972f6Sopenharmony_ci         }
44195972f6Sopenharmony_ci         tcp_seg_free(rseg);
45195972f6Sopenharmony_ci 
46195972f6Sopenharmony_ci@@ -1393,6 +1399,8 @@ tcp_receive(struct tcp_pcb *pcb)
47195972f6Sopenharmony_ci       /* Remove segment from the unacknowledged list if the incoming
48195972f6Sopenharmony_ci          ACK acknowledges them. */
49195972f6Sopenharmony_ci       pcb->unacked = tcp_free_acked_segments(pcb, pcb->unacked, "unacked", pcb->unsent);
50195972f6Sopenharmony_ci+      if (pcb->unacked == NULL)
51195972f6Sopenharmony_ci+        pcb->last_unacked = NULL;
52195972f6Sopenharmony_ci       /* We go through the ->unsent list to see if any of the segments
53195972f6Sopenharmony_ci          on the list are acknowledged by the ACK. This may seem
54195972f6Sopenharmony_ci          strange since an "unsent" segment shouldn't be acked. The
55195972f6Sopenharmony_ci@@ -1400,6 +1408,8 @@ tcp_receive(struct tcp_pcb *pcb)
56195972f6Sopenharmony_ci          ->unsent list after a retransmission, so these segments may
57195972f6Sopenharmony_ci          in fact have been sent once. */
58195972f6Sopenharmony_ci       pcb->unsent = tcp_free_acked_segments(pcb, pcb->unsent, "unsent", pcb->unacked);
59195972f6Sopenharmony_ci+      if (pcb->unsent == NULL)
60195972f6Sopenharmony_ci+        pcb->last_unsent = NULL;
61195972f6Sopenharmony_ci 
62195972f6Sopenharmony_ci       /* If there's nothing left to acknowledge, stop the retransmit
63195972f6Sopenharmony_ci          timer, otherwise reset it to start again */
64195972f6Sopenharmony_ci@@ -1736,7 +1746,11 @@ tcp_receive(struct tcp_pcb *pcb)
65195972f6Sopenharmony_ci 
66195972f6Sopenharmony_ci 
67195972f6Sopenharmony_ci         /* Acknowledge the segment(s). */
68195972f6Sopenharmony_ci-        tcp_ack(pcb);
69195972f6Sopenharmony_ci+        if (flags & TCP_PSH) {
70195972f6Sopenharmony_ci+            tcp_ack_now(pcb);
71195972f6Sopenharmony_ci+        } else {
72195972f6Sopenharmony_ci+            tcp_ack(pcb);
73195972f6Sopenharmony_ci+        }
74195972f6Sopenharmony_ci 
75195972f6Sopenharmony_ci #if LWIP_TCP_SACK_OUT
76195972f6Sopenharmony_ci         if (LWIP_TCP_SACK_VALID(pcb, 0)) {
77195972f6Sopenharmony_cidiff --git a/src/core/tcp_out.c b/src/core/tcp_out.c
78195972f6Sopenharmony_ciindex f53750b..55053d8 100644
79195972f6Sopenharmony_ci--- a/src/core/tcp_out.c
80195972f6Sopenharmony_ci+++ b/src/core/tcp_out.c
81195972f6Sopenharmony_ci@@ -631,11 +631,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
82195972f6Sopenharmony_ci #endif /* TCP_OVERSIZE */
83195972f6Sopenharmony_ci   }
84195972f6Sopenharmony_ci #else /* USE_LIBOS */
85195972f6Sopenharmony_ci-  if (pcb->unsent != NULL) {
86195972f6Sopenharmony_ci-    /* @todo: this could be sped up by keeping last_unsent in the pcb */
87195972f6Sopenharmony_ci-    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
88195972f6Sopenharmony_ci-         last_unsent = last_unsent->next);
89195972f6Sopenharmony_ci-  }
90195972f6Sopenharmony_ci+  last_unsent = pcb->last_unsent;
91195972f6Sopenharmony_ci #endif /* USE_LIBOS */
92195972f6Sopenharmony_ci 
93195972f6Sopenharmony_ci   /*
94195972f6Sopenharmony_ci@@ -851,6 +847,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
95195972f6Sopenharmony_ci    * Finally update the pcb state.
96195972f6Sopenharmony_ci    */
97195972f6Sopenharmony_ci #if USE_LIBOS
98195972f6Sopenharmony_ci+  if (queue) {
99195972f6Sopenharmony_ci+    pcb->last_unsent = prev_seg;
100195972f6Sopenharmony_ci+  }
101195972f6Sopenharmony_ci   pcb->snd_lbb += pos;
102195972f6Sopenharmony_ci   pcb->snd_buf -= pos;
103195972f6Sopenharmony_ci #else
104195972f6Sopenharmony_ci@@ -1050,6 +1049,8 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
105195972f6Sopenharmony_ci   /* Finally insert remainder into queue after split (which stays head) */
106195972f6Sopenharmony_ci   seg->next = useg->next;
107195972f6Sopenharmony_ci   useg->next = seg;
108195972f6Sopenharmony_ci+  if (pcb->last_unsent == useg)
109195972f6Sopenharmony_ci+    pcb->last_unsent = seg;
110195972f6Sopenharmony_ci 
111195972f6Sopenharmony_ci #if TCP_OVERSIZE
112195972f6Sopenharmony_ci   /* If remainder is last segment on the unsent, ensure we clear the oversize amount
113195972f6Sopenharmony_ci@@ -1086,9 +1087,7 @@ tcp_send_fin(struct tcp_pcb *pcb)
114195972f6Sopenharmony_ci 
115195972f6Sopenharmony_ci   /* first, try to add the fin to the last unsent segment */
116195972f6Sopenharmony_ci   if (pcb->unsent != NULL) {
117195972f6Sopenharmony_ci-    struct tcp_seg *last_unsent;
118195972f6Sopenharmony_ci-    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
119195972f6Sopenharmony_ci-         last_unsent = last_unsent->next);
120195972f6Sopenharmony_ci+    struct tcp_seg *last_unsent = pcb->unsent;
121195972f6Sopenharmony_ci 
122195972f6Sopenharmony_ci     if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
123195972f6Sopenharmony_ci       /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
124195972f6Sopenharmony_ci@@ -1182,10 +1181,10 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
125195972f6Sopenharmony_ci   if (pcb->unsent == NULL) {
126195972f6Sopenharmony_ci     pcb->unsent = seg;
127195972f6Sopenharmony_ci   } else {
128195972f6Sopenharmony_ci-    struct tcp_seg *useg;
129195972f6Sopenharmony_ci-    for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
130195972f6Sopenharmony_ci+    struct tcp_seg *useg = pcb->last_unsent;
131195972f6Sopenharmony_ci     useg->next = seg;
132195972f6Sopenharmony_ci   }
133195972f6Sopenharmony_ci+  pcb->last_unsent = seg;
134195972f6Sopenharmony_ci #if TCP_OVERSIZE
135195972f6Sopenharmony_ci   /* The new unsent tail has no space */
136195972f6Sopenharmony_ci   pcb->unsent_oversize = 0;
137195972f6Sopenharmony_ci@@ -1314,6 +1313,7 @@ static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg,
138195972f6Sopenharmony_ci     seg->next = NULL;
139195972f6Sopenharmony_ci     if (useg == NULL) {
140195972f6Sopenharmony_ci       pcb->unacked = seg;
141195972f6Sopenharmony_ci+      pcb->last_unacked = seg;
142195972f6Sopenharmony_ci       useg = seg;
143195972f6Sopenharmony_ci     } else {
144195972f6Sopenharmony_ci       if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) {
145195972f6Sopenharmony_ci@@ -1329,6 +1329,7 @@ static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg,
146195972f6Sopenharmony_ci         /* add segment to tail of unacked list */
147195972f6Sopenharmony_ci         useg->next = seg;
148195972f6Sopenharmony_ci         useg = seg;
149195972f6Sopenharmony_ci+        pcb->last_unacked = seg;
150195972f6Sopenharmony_ci       }
151195972f6Sopenharmony_ci     }
152195972f6Sopenharmony_ci   } else {
153195972f6Sopenharmony_ci@@ -1460,15 +1461,14 @@ tcp_output(struct tcp_pcb *pcb)
154195972f6Sopenharmony_ci   pcb->persist_backoff = 0;
155195972f6Sopenharmony_ci 
156195972f6Sopenharmony_ci   /* useg should point to last segment on unacked queue */
157195972f6Sopenharmony_ci-  useg = pcb->unacked;
158195972f6Sopenharmony_ci-  if (useg != NULL) {
159195972f6Sopenharmony_ci-    for (; useg->next != NULL; useg = useg->next);
160195972f6Sopenharmony_ci-  }
161195972f6Sopenharmony_ci+  useg = pcb->last_unacked;
162195972f6Sopenharmony_ci+
163195972f6Sopenharmony_ci   /* data available and window allows it to be sent? */
164195972f6Sopenharmony_ci 
165195972f6Sopenharmony_ci+  u32_t send_len = 0;
166195972f6Sopenharmony_ci #if USE_LIBOS
167195972f6Sopenharmony_ci   if (get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_TSO) {
168195972f6Sopenharmony_ci-    while(seg) {
169195972f6Sopenharmony_ci+    while(seg && send_len < 0xffff) {
170195972f6Sopenharmony_ci       /**
171195972f6Sopenharmony_ci        * 1)遍历unsent队列,找到所有的待发送seg. 将seg的buf串起来
172195972f6Sopenharmony_ci        * 2) 生成新的seg, 调用tcp_output_segment, 新的seg释放掉
173195972f6Sopenharmony_ci@@ -1510,6 +1510,7 @@ tcp_output(struct tcp_pcb *pcb)
174195972f6Sopenharmony_ci           pre_pbuf->next = seg->p;
175195972f6Sopenharmony_ci         }
176195972f6Sopenharmony_ci 
177195972f6Sopenharmony_ci+        send_len += seg->len;
178195972f6Sopenharmony_ci         pre_pbuf = seg->p;
179195972f6Sopenharmony_ci         next_seqno = seg_seqno + TCP_TCPLEN(seg);
180195972f6Sopenharmony_ci         seg = seg->next;
181195972f6Sopenharmony_ci@@ -1519,8 +1520,11 @@ tcp_output(struct tcp_pcb *pcb)
182195972f6Sopenharmony_ci 
183195972f6Sopenharmony_ci       if (first_pbuf == NULL) {
184195972f6Sopenharmony_ci         err = tcp_output_seg(pcb, seg, netif, next_seqno + seg->len);
185195972f6Sopenharmony_ci-        if (err != ERR_OK)
186195972f6Sopenharmony_ci+        if (err != ERR_OK) {
187195972f6Sopenharmony_ci+          if (pcb->unsent == NULL)
188195972f6Sopenharmony_ci+            pcb->last_unsent = NULL;
189195972f6Sopenharmony_ci           return err;
190195972f6Sopenharmony_ci+        }
191195972f6Sopenharmony_ci         pcb->unsent = seg->next;
192195972f6Sopenharmony_ci         useg = tcp_output_over(pcb, seg, useg);
193195972f6Sopenharmony_ci         seg = pcb->unsent;
194195972f6Sopenharmony_ci@@ -1545,7 +1549,7 @@ tcp_output(struct tcp_pcb *pcb)
195195972f6Sopenharmony_ci   } else
196195972f6Sopenharmony_ci #endif
197195972f6Sopenharmony_ci {
198195972f6Sopenharmony_ci-  while (seg != NULL &&
199195972f6Sopenharmony_ci+  while (seg != NULL && send_len < 0xffff &&
200195972f6Sopenharmony_ci          lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
201195972f6Sopenharmony_ci     LWIP_ASSERT("RST not expected here!",
202195972f6Sopenharmony_ci                 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
203195972f6Sopenharmony_ci@@ -1560,6 +1564,7 @@ tcp_output(struct tcp_pcb *pcb)
204195972f6Sopenharmony_ci         ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) {
205195972f6Sopenharmony_ci       break;
206195972f6Sopenharmony_ci     }
207195972f6Sopenharmony_ci+    send_len += seg->len;
208195972f6Sopenharmony_ci #if TCP_CWND_DEBUG
209195972f6Sopenharmony_ci     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
210195972f6Sopenharmony_ci                                  pcb->snd_wnd, pcb->cwnd, wnd,
211195972f6Sopenharmony_ci@@ -1577,6 +1582,8 @@ tcp_output(struct tcp_pcb *pcb)
212195972f6Sopenharmony_ci     if (err != ERR_OK) {
213195972f6Sopenharmony_ci       /* segment could not be sent, for whatever reason */
214195972f6Sopenharmony_ci       tcp_set_flags(pcb, TF_NAGLEMEMERR);
215195972f6Sopenharmony_ci+      if (pcb->unsent == NULL)
216195972f6Sopenharmony_ci+        pcb->last_unsent = NULL;
217195972f6Sopenharmony_ci       return err;
218195972f6Sopenharmony_ci     }
219195972f6Sopenharmony_ci #if TCP_OVERSIZE_DBGCHECK
220195972f6Sopenharmony_ci@@ -1596,6 +1603,7 @@ tcp_output(struct tcp_pcb *pcb)
221195972f6Sopenharmony_ci       /* unacked list is empty? */
222195972f6Sopenharmony_ci       if (pcb->unacked == NULL) {
223195972f6Sopenharmony_ci         pcb->unacked = seg;
224195972f6Sopenharmony_ci+        pcb->last_unacked = seg;
225195972f6Sopenharmony_ci         useg = seg;
226195972f6Sopenharmony_ci         /* unacked list is not empty? */
227195972f6Sopenharmony_ci       } else {
228195972f6Sopenharmony_ci@@ -1615,6 +1623,7 @@ tcp_output(struct tcp_pcb *pcb)
229195972f6Sopenharmony_ci           /* add segment to tail of unacked list */
230195972f6Sopenharmony_ci           useg->next = seg;
231195972f6Sopenharmony_ci           useg = useg->next;
232195972f6Sopenharmony_ci+          pcb->last_unacked = seg;
233195972f6Sopenharmony_ci         }
234195972f6Sopenharmony_ci       }
235195972f6Sopenharmony_ci       /* do not queue empty segments on the unacked list */
236195972f6Sopenharmony_ci@@ -1632,6 +1641,8 @@ tcp_output(struct tcp_pcb *pcb)
237195972f6Sopenharmony_ci #endif /* TCP_OVERSIZE */
238195972f6Sopenharmony_ci 
239195972f6Sopenharmony_ci output_done:
240195972f6Sopenharmony_ci+  if (pcb->unsent == NULL)
241195972f6Sopenharmony_ci+    pcb->last_unsent = NULL;
242195972f6Sopenharmony_ci   tcp_clear_flags(pcb, TF_NAGLEMEMERR);
243195972f6Sopenharmony_ci   return ERR_OK;
244195972f6Sopenharmony_ci }
245195972f6Sopenharmony_ci@@ -1932,9 +1943,13 @@ tcp_rexmit_rto_prepare(struct tcp_pcb *pcb)
246195972f6Sopenharmony_ci   }
247195972f6Sopenharmony_ci #endif /* TCP_OVERSIZE_DBGCHECK */
248195972f6Sopenharmony_ci   /* unsent queue is the concatenated queue (of unacked, unsent) */
249195972f6Sopenharmony_ci+  if (pcb->unsent == NULL) {
250195972f6Sopenharmony_ci+    pcb->last_unsent = pcb->last_unacked;
251195972f6Sopenharmony_ci+  }
252195972f6Sopenharmony_ci   pcb->unsent = pcb->unacked;
253195972f6Sopenharmony_ci   /* unacked queue is now empty */
254195972f6Sopenharmony_ci   pcb->unacked = NULL;
255195972f6Sopenharmony_ci+  pcb->last_unacked = NULL;
256195972f6Sopenharmony_ci 
257195972f6Sopenharmony_ci   /* Mark RTO in-progress */
258195972f6Sopenharmony_ci   tcp_set_flags(pcb, TF_RTO);
259195972f6Sopenharmony_ci@@ -2004,32 +2019,42 @@ tcp_rexmit(struct tcp_pcb *pcb)
260195972f6Sopenharmony_ci   }
261195972f6Sopenharmony_ci 
262195972f6Sopenharmony_ci   seg = pcb->unacked;
263195972f6Sopenharmony_ci+  while (seg) {
264195972f6Sopenharmony_ci+    /* Give up if the segment is still referenced by the netif driver
265195972f6Sopenharmony_ci+      due to deferred transmission. */
266195972f6Sopenharmony_ci+    if (tcp_output_segment_busy(seg)) {
267195972f6Sopenharmony_ci+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit busy\n"));
268195972f6Sopenharmony_ci+      if (seg == pcb->unacked)
269195972f6Sopenharmony_ci+        return ERR_VAL;
270195972f6Sopenharmony_ci+      else
271195972f6Sopenharmony_ci+        break;
272195972f6Sopenharmony_ci+    }
273195972f6Sopenharmony_ci 
274195972f6Sopenharmony_ci-  /* Give up if the segment is still referenced by the netif driver
275195972f6Sopenharmony_ci-     due to deferred transmission. */
276195972f6Sopenharmony_ci-  if (tcp_output_segment_busy(seg)) {
277195972f6Sopenharmony_ci-    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit busy\n"));
278195972f6Sopenharmony_ci-    return ERR_VAL;
279195972f6Sopenharmony_ci-  }
280195972f6Sopenharmony_ci-
281195972f6Sopenharmony_ci-  /* Move the first unacked segment to the unsent queue */
282195972f6Sopenharmony_ci-  /* Keep the unsent queue sorted. */
283195972f6Sopenharmony_ci-  pcb->unacked = seg->next;
284195972f6Sopenharmony_ci+    /* Move the first unacked segment to the unsent queue */
285195972f6Sopenharmony_ci+    /* Keep the unsent queue sorted. */
286195972f6Sopenharmony_ci+    if (pcb->last_unacked == pcb->unacked)
287195972f6Sopenharmony_ci+      pcb->last_unacked = pcb->unacked->next;
288195972f6Sopenharmony_ci+    pcb->unacked = pcb->unacked->next;
289195972f6Sopenharmony_ci 
290195972f6Sopenharmony_ci-  cur_seg = &(pcb->unsent);
291195972f6Sopenharmony_ci-  while (*cur_seg &&
292195972f6Sopenharmony_ci-         TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) {
293195972f6Sopenharmony_ci-    cur_seg = &((*cur_seg)->next );
294195972f6Sopenharmony_ci-  }
295195972f6Sopenharmony_ci-  seg->next = *cur_seg;
296195972f6Sopenharmony_ci-  *cur_seg = seg;
297195972f6Sopenharmony_ci+    cur_seg = &(pcb->unsent);
298195972f6Sopenharmony_ci+    while (*cur_seg &&
299195972f6Sopenharmony_ci+          TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) {
300195972f6Sopenharmony_ci+      cur_seg = &((*cur_seg)->next);
301195972f6Sopenharmony_ci+    }
302195972f6Sopenharmony_ci+    if (*cur_seg == NULL)
303195972f6Sopenharmony_ci+      pcb->last_unsent = seg;
304195972f6Sopenharmony_ci+    seg->next = *cur_seg;
305195972f6Sopenharmony_ci+    *cur_seg = seg;
306195972f6Sopenharmony_ci #if TCP_OVERSIZE
307195972f6Sopenharmony_ci-  if (seg->next == NULL) {
308195972f6Sopenharmony_ci-    /* the retransmitted segment is last in unsent, so reset unsent_oversize */
309195972f6Sopenharmony_ci-    pcb->unsent_oversize = 0;
310195972f6Sopenharmony_ci-  }
311195972f6Sopenharmony_ci+    if (seg->next == NULL) {
312195972f6Sopenharmony_ci+      /* the retransmitted segment is last in unsent, so reset unsent_oversize */
313195972f6Sopenharmony_ci+      pcb->unsent_oversize = 0;
314195972f6Sopenharmony_ci+    }
315195972f6Sopenharmony_ci #endif /* TCP_OVERSIZE */
316195972f6Sopenharmony_ci 
317195972f6Sopenharmony_ci+    seg = pcb->unacked;
318195972f6Sopenharmony_ci+  }
319195972f6Sopenharmony_ci+
320195972f6Sopenharmony_ci   if (pcb->nrtx < 0xFF) {
321195972f6Sopenharmony_ci     ++pcb->nrtx;
322195972f6Sopenharmony_ci   }
323195972f6Sopenharmony_ci@@ -2207,7 +2232,7 @@ tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p,
324195972f6Sopenharmony_ci       struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload;
325195972f6Sopenharmony_ci #if CHECKSUM_GEN_TCP_HW
326195972f6Sopenharmony_ci     if (get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_CKSUM) {
327195972f6Sopenharmony_ci-      tcph_cksum_set(p, TCP_HLEN);
328195972f6Sopenharmony_ci+      tcph_cksum_set(p, TCPH_HDRLEN_BYTES(tcphdr));
329195972f6Sopenharmony_ci       tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP, p->tot_len, src, dst);
330195972f6Sopenharmony_ci     } else {
331195972f6Sopenharmony_ci       tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
332195972f6Sopenharmony_cidiff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h
333195972f6Sopenharmony_ciindex 8294cdd..83e7e93 100644
334195972f6Sopenharmony_ci--- a/src/include/lwip/opt.h
335195972f6Sopenharmony_ci+++ b/src/include/lwip/opt.h
336195972f6Sopenharmony_ci@@ -1281,7 +1281,7 @@
337195972f6Sopenharmony_ci  * LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs).
338195972f6Sopenharmony_ci  */
339195972f6Sopenharmony_ci #if !defined LWIP_TCP_SACK_OUT || defined __DOXYGEN__
340195972f6Sopenharmony_ci-#define LWIP_TCP_SACK_OUT               0
341195972f6Sopenharmony_ci+#define LWIP_TCP_SACK_OUT               1
342195972f6Sopenharmony_ci #endif
343195972f6Sopenharmony_ci 
344195972f6Sopenharmony_ci /**
345195972f6Sopenharmony_cidiff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
346195972f6Sopenharmony_ciindex b36bf33..b0ae02c 100644
347195972f6Sopenharmony_ci--- a/src/include/lwip/tcp.h
348195972f6Sopenharmony_ci+++ b/src/include/lwip/tcp.h
349195972f6Sopenharmony_ci@@ -356,7 +356,9 @@ struct tcp_pcb {
350195972f6Sopenharmony_ci 
351195972f6Sopenharmony_ci   /* These are ordered by sequence number: */
352195972f6Sopenharmony_ci   struct tcp_seg *unsent;   /* Unsent (queued) segments. */
353195972f6Sopenharmony_ci+  struct tcp_seg *last_unsent;
354195972f6Sopenharmony_ci   struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */
355195972f6Sopenharmony_ci+  struct tcp_seg *last_unacked;
356195972f6Sopenharmony_ci #if TCP_QUEUE_OOSEQ
357195972f6Sopenharmony_ci   struct tcp_seg *ooseq;    /* Received out of sequence segments. */
358195972f6Sopenharmony_ci #endif /* TCP_QUEUE_OOSEQ */
359195972f6Sopenharmony_cidiff --git a/src/include/lwipsock.h b/src/include/lwipsock.h
360195972f6Sopenharmony_ciindex f919330..bf0d753 100644
361195972f6Sopenharmony_ci--- a/src/include/lwipsock.h
362195972f6Sopenharmony_ci+++ b/src/include/lwipsock.h
363195972f6Sopenharmony_ci@@ -112,8 +112,6 @@ struct lwip_sock {
364195972f6Sopenharmony_ci   struct list_node send_list;
365195972f6Sopenharmony_ci   struct pbuf *send_lastdata;
366195972f6Sopenharmony_ci   struct pbuf *send_pre_del;
367195972f6Sopenharmony_ci-  uint64_t recv_all;
368195972f6Sopenharmony_ci-  uint64_t send_all;
369195972f6Sopenharmony_ci 
370195972f6Sopenharmony_ci   char pad3 __rte_cache_aligned;
371195972f6Sopenharmony_ci   /* nerver change */
372195972f6Sopenharmony_ci-- 
373195972f6Sopenharmony_ci2.8.4.windows.1
374195972f6Sopenharmony_ci
375