Skip to content

Commit 297e7c3

Browse files
committed
Guard UDP RX FIFO enqueue state
F/1778
1 parent a82e562 commit 297e7c3

3 files changed

Lines changed: 74 additions & 3 deletions

File tree

src/test/unit/unit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ Suite *wolf_suite(void)
342342
tcase_add_test(tc_utils, test_udp_try_recv_remote_ip_matches_local_ip);
343343
tcase_add_test(tc_utils, test_udp_try_recv_unmatched_port_sends_icmp_unreachable);
344344
tcase_add_test(tc_utils, test_udp_try_recv_unmatched_nonlocal_dst_does_not_send_icmp);
345+
tcase_add_test(tc_utils, test_udp_try_recv_full_fifo_drop_does_not_set_readable_or_suppress_icmp);
345346
tcase_add_test(tc_utils, test_dns_callback_bad_flags);
346347
tcase_add_test(tc_utils, test_dns_callback_truncated_response_aborts_query);
347348
tcase_add_test(tc_utils, test_dns_callback_bad_name);

src/test/unit/unit_tests_dns_dhcp.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4751,6 +4751,75 @@ START_TEST(test_udp_try_recv_unmatched_nonlocal_dst_does_not_send_icmp)
47514751
}
47524752
END_TEST
47534753

4754+
START_TEST(test_udp_try_recv_full_fifo_drop_does_not_set_readable_or_suppress_icmp)
4755+
{
4756+
struct wolfIP s;
4757+
struct tsocket *ts;
4758+
uint8_t udp_buf[sizeof(struct wolfIP_udp_datagram) + 4];
4759+
struct wolfIP_udp_datagram *udp = (struct wolfIP_udp_datagram *)udp_buf;
4760+
struct wolfIP_icmp_dest_unreachable_packet *icmp;
4761+
uint32_t local_ip = 0x0A000001U;
4762+
uint32_t remote_ip = 0x0A000002U;
4763+
uint8_t src_mac[6] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25};
4764+
uint32_t frame_len = (uint32_t)(ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN + 4);
4765+
uint32_t head_before;
4766+
uint32_t tail_before;
4767+
uint32_t h_wrap_before;
4768+
4769+
wolfIP_init(&s);
4770+
mock_link_init(&s);
4771+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
4772+
4773+
ts = udp_new_socket(&s);
4774+
ck_assert_ptr_nonnull(ts);
4775+
ts->src_port = 1234;
4776+
ts->local_ip = local_ip;
4777+
4778+
memset(udp_buf, 0, sizeof(udp_buf));
4779+
memcpy(udp->ip.eth.src, src_mac, sizeof(src_mac));
4780+
memcpy(udp->ip.eth.dst, s.ll_dev[TEST_PRIMARY_IF].mac, 6);
4781+
udp->ip.eth.type = ee16(ETH_TYPE_IP);
4782+
udp->ip.ver_ihl = 0x45;
4783+
udp->ip.ttl = 64;
4784+
udp->ip.proto = WI_IPPROTO_UDP;
4785+
udp->ip.len = ee16(IP_HEADER_LEN + UDP_HEADER_LEN + 4);
4786+
udp->ip.src = ee32(remote_ip);
4787+
udp->ip.dst = ee32(local_ip);
4788+
udp->src_port = ee16(4321);
4789+
udp->dst_port = ee16(1234);
4790+
udp->len = ee16(UDP_HEADER_LEN + 4);
4791+
memcpy(udp->data, "test", 4);
4792+
fix_udp_checksums(udp);
4793+
4794+
/* Mirror the FIFO's canonical full state: head == tail with wrap set. */
4795+
ts->sock.udp.rxbuf.head = 0;
4796+
ts->sock.udp.rxbuf.tail = 0;
4797+
ts->sock.udp.rxbuf.h_wrap = ts->sock.udp.rxbuf.size;
4798+
ck_assert_int_eq(fifo_can_push_len(&ts->sock.udp.rxbuf, frame_len), 0);
4799+
4800+
head_before = ts->sock.udp.rxbuf.head;
4801+
tail_before = ts->sock.udp.rxbuf.tail;
4802+
h_wrap_before = ts->sock.udp.rxbuf.h_wrap;
4803+
ts->events = 0;
4804+
4805+
memset(last_frame_sent, 0, sizeof(last_frame_sent));
4806+
last_frame_sent_size = 0;
4807+
4808+
udp_try_recv(&s, TEST_PRIMARY_IF, udp, frame_len);
4809+
4810+
ck_assert_uint_eq(ts->events & CB_EVENT_READABLE, 0U);
4811+
ck_assert_uint_eq(ts->sock.udp.rxbuf.head, head_before);
4812+
ck_assert_uint_eq(ts->sock.udp.rxbuf.tail, tail_before);
4813+
ck_assert_uint_eq(ts->sock.udp.rxbuf.h_wrap, h_wrap_before);
4814+
ck_assert_uint_eq(last_frame_sent_size,
4815+
sizeof(struct wolfIP_icmp_dest_unreachable_packet));
4816+
4817+
icmp = (struct wolfIP_icmp_dest_unreachable_packet *)last_frame_sent;
4818+
ck_assert_uint_eq(icmp->type, 3U);
4819+
ck_assert_uint_eq(icmp->code, 3U);
4820+
}
4821+
END_TEST
4822+
47544823
START_TEST(test_dns_callback_bad_flags)
47554824
{
47564825
struct wolfIP s;

src/wolfip.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,9 +1911,10 @@ static void udp_try_recv(struct wolfIP *s, unsigned int if_idx,
19111911
if ((int)frame_len < (int)expected_len)
19121912
return;
19131913
/* Insert into socket buffer */
1914-
fifo_push(&t->sock.udp.rxbuf, udp, frame_len);
1915-
t->events |= CB_EVENT_READABLE;
1916-
matched = 1;
1914+
if (fifo_push(&t->sock.udp.rxbuf, udp, frame_len) == 0) {
1915+
t->events |= CB_EVENT_READABLE;
1916+
matched = 1;
1917+
}
19171918
}
19181919
}
19191920
if (!matched) {

0 commit comments

Comments
 (0)