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