Skip to content

Commit d632302

Browse files
committed
Fix: PSH flag must be set on last segment
1 parent cf05622 commit d632302

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

src/test/unit/unit.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,6 +3642,7 @@ START_TEST(test_sock_sendto_tcp_multiple_segments_flags)
36423642
ck_assert_int_gt(tcp_sd, 0);
36433643
ts = &s.tcpsockets[SOCKET_UNMARK(tcp_sd)];
36443644
ts->sock.tcp.state = TCP_ESTABLISHED;
3645+
ts->sock.tcp.peer_mss = TCP_MSS;
36453646
ts->src_port = 1234;
36463647
ts->dst_port = 4321;
36473648
ts->local_ip = 0x0A000001U;
@@ -3656,12 +3657,12 @@ START_TEST(test_sock_sendto_tcp_multiple_segments_flags)
36563657
first = fifo_peek(&ts->sock.tcp.txbuf);
36573658
ck_assert_ptr_nonnull(first);
36583659
tcp1 = (struct wolfIP_tcp_seg *)(txbuf + first->pos + sizeof(*first));
3659-
ck_assert_uint_eq(tcp1->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), (TCP_FLAG_ACK | TCP_FLAG_PSH));
3660+
ck_assert_uint_eq(tcp1->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), TCP_FLAG_ACK);
36603661

36613662
second = fifo_next(&ts->sock.tcp.txbuf, first);
36623663
ck_assert_ptr_nonnull(second);
36633664
tcp2 = (struct wolfIP_tcp_seg *)(txbuf + second->pos + sizeof(*second));
3664-
ck_assert_uint_eq(tcp2->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), TCP_FLAG_ACK);
3665+
ck_assert_uint_eq(tcp2->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), (TCP_FLAG_ACK | TCP_FLAG_PSH));
36653666
}
36663667
END_TEST
36673668

src/wolfip.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3896,7 +3896,7 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len
38963896
tcp->seq = ee32(ts->sock.tcp.seq);
38973897
tcp->ack = ee32(ts->sock.tcp.ack);
38983898
tcp->hlen = (uint8_t)((TCP_HEADER_LEN + opt_len) << 2);
3899-
tcp->flags = TCP_FLAG_ACK | ((sent == 0) ? TCP_FLAG_PSH : 0); /* ACK; PSH only on first */
3899+
tcp->flags = TCP_FLAG_ACK;
39003900
tcp->win = ee16(tcp_adv_win(ts));
39013901
tcp->csum = 0;
39023902
tcp->urg = 0;
@@ -3922,8 +3922,27 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len
39223922
}
39233923
if (sent == 0) {
39243924
return -WOLFIP_EAGAIN;
3925-
} else
3925+
} else {
3926+
struct pkt_desc *desc;
3927+
struct pkt_desc *last_desc = NULL;
3928+
uint32_t guard = 0;
3929+
uint32_t budget = fifo_desc_budget(&ts->sock.tcp.txbuf);
3930+
desc = fifo_peek(&ts->sock.tcp.txbuf);
3931+
while (desc && guard++ < budget) {
3932+
struct pkt_desc *next = fifo_next(&ts->sock.tcp.txbuf, desc);
3933+
last_desc = desc;
3934+
if (next == desc)
3935+
break;
3936+
desc = next;
3937+
}
3938+
if (last_desc) {
3939+
/* PSH flag is set on the last segment in this train */
3940+
struct wolfIP_tcp_seg *last_tcp =
3941+
(struct wolfIP_tcp_seg *)((uint8_t *)last_desc + sizeof(*last_desc));
3942+
last_tcp->flags |= TCP_FLAG_PSH;
3943+
}
39263944
return sent;
3945+
}
39273946
} else if (IS_SOCKET_UDP(sockfd)) {
39283947
const struct wolfIP_sockaddr_in *sin = (const struct wolfIP_sockaddr_in *)dest_addr;
39293948
unsigned int if_idx;

0 commit comments

Comments
 (0)