Skip to content

Commit 1876cdf

Browse files
authored
Merge pull request #52 from danielinux/fix_psh_last_seg
Fix: PSH flag must be set on last segment
2 parents d708ee0 + 9fe9950 commit 1876cdf

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

src/test/unit/unit.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3685,6 +3685,7 @@ START_TEST(test_sock_sendto_tcp_multiple_segments_flags)
36853685
ck_assert_int_gt(tcp_sd, 0);
36863686
ts = &s.tcpsockets[SOCKET_UNMARK(tcp_sd)];
36873687
ts->sock.tcp.state = TCP_ESTABLISHED;
3688+
ts->sock.tcp.peer_mss = TCP_MSS;
36883689
ts->src_port = 1234;
36893690
ts->dst_port = 4321;
36903691
ts->local_ip = 0x0A000001U;
@@ -3699,12 +3700,12 @@ START_TEST(test_sock_sendto_tcp_multiple_segments_flags)
36993700
first = fifo_peek(&ts->sock.tcp.txbuf);
37003701
ck_assert_ptr_nonnull(first);
37013702
tcp1 = (struct wolfIP_tcp_seg *)(txbuf + first->pos + sizeof(*first));
3702-
ck_assert_uint_eq(tcp1->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), (TCP_FLAG_ACK | TCP_FLAG_PSH));
3703+
ck_assert_uint_eq(tcp1->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), TCP_FLAG_ACK);
37033704

37043705
second = fifo_next(&ts->sock.tcp.txbuf, first);
37053706
ck_assert_ptr_nonnull(second);
37063707
tcp2 = (struct wolfIP_tcp_seg *)(txbuf + second->pos + sizeof(*second));
3707-
ck_assert_uint_eq(tcp2->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), TCP_FLAG_ACK);
3708+
ck_assert_uint_eq(tcp2->flags & (TCP_FLAG_ACK | TCP_FLAG_PSH), (TCP_FLAG_ACK | TCP_FLAG_PSH));
37083709
}
37093710
END_TEST
37103711

src/wolfip.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ struct PACKED pkt_desc {
154154

155155
struct fifo {
156156
uint32_t head, tail, size, h_wrap;
157+
uint32_t last_pos;
158+
uint8_t last_valid;
157159
uint8_t *data;
158160
};
159161

@@ -208,6 +210,8 @@ static void fifo_init(struct fifo *f, uint8_t *data, uint32_t size)
208210
f->tail = 0;
209211
f->h_wrap = 0;
210212
f->size = size;
213+
f->last_pos = 0;
214+
f->last_valid = 0;
211215
f->data = data;
212216
}
213217

@@ -361,6 +365,8 @@ static int fifo_push(struct fifo *f, void *data, uint32_t len)
361365
}
362366
f->head = head;
363367
f->h_wrap = h_wrap;
368+
f->last_pos = desc.pos;
369+
f->last_valid = 1;
364370
return 0;
365371
}
366372

@@ -479,6 +485,8 @@ static struct pkt_desc *fifo_pop(struct fifo *f)
479485
f->h_wrap = 0;
480486
if (f->tail >= f->size)
481487
f->tail %= f->size;
488+
if (fifo_is_empty(f))
489+
f->last_valid = 0;
482490
return desc;
483491
}
484492

@@ -3869,6 +3877,8 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len
38693877
if (IS_SOCKET_TCP(sockfd)) {
38703878
size_t sent = 0;
38713879
unsigned int push_iter = 0;
3880+
uint32_t last_desc_pos = 0;
3881+
int last_desc_valid = 0;
38723882
if (SOCKET_UNMARK(sockfd) >= MAX_TCPSOCKETS)
38733883
return -WOLFIP_EINVAL;
38743884

@@ -3897,7 +3907,7 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len
38973907
tcp->seq = ee32(ts->sock.tcp.seq);
38983908
tcp->ack = ee32(ts->sock.tcp.ack);
38993909
tcp->hlen = (uint8_t)((TCP_HEADER_LEN + opt_len) << 2);
3900-
tcp->flags = TCP_FLAG_ACK | ((sent == 0) ? TCP_FLAG_PSH : 0); /* ACK; PSH only on first */
3910+
tcp->flags = TCP_FLAG_ACK;
39013911
tcp->win = ee16(tcp_adv_win(ts));
39023912
tcp->csum = 0;
39033913
tcp->urg = 0;
@@ -3915,6 +3925,10 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len
39153925
sizeof(struct wolfIP_tcp_seg) + opt_len + payload_len) < 0) {
39163926
break;
39173927
}
3928+
if (ts->sock.tcp.txbuf.last_valid) {
3929+
last_desc_pos = ts->sock.tcp.txbuf.last_pos;
3930+
last_desc_valid = 1;
3931+
}
39183932
sent += payload_len;
39193933
ts->sock.tcp.seq += payload_len;
39203934
if (push_iter > 256) {
@@ -3923,8 +3937,16 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len
39233937
}
39243938
if (sent == 0) {
39253939
return -WOLFIP_EAGAIN;
3926-
} else
3940+
} else {
3941+
if (last_desc_valid) {
3942+
struct pkt_desc *last_desc =
3943+
(struct pkt_desc *)(ts->sock.tcp.txbuf.data + last_desc_pos);
3944+
struct wolfIP_tcp_seg *last_tcp =
3945+
(struct wolfIP_tcp_seg *)((uint8_t *)last_desc + sizeof(*last_desc));
3946+
last_tcp->flags |= TCP_FLAG_PSH;
3947+
}
39273948
return sent;
3949+
}
39283950
} else if (IS_SOCKET_UDP(sockfd)) {
39293951
const struct wolfIP_sockaddr_in *sin = (const struct wolfIP_sockaddr_in *)dest_addr;
39303952
unsigned int if_idx;

0 commit comments

Comments
 (0)