Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
407178b
F-6209: keep raw/packet TX descriptor queued on driver backpressure
danielinux Aug 21, 2026
5815e8a
F-10259: clear raw/packet socket events before dispatching the callback
danielinux Aug 21, 2026
855ad2c
F-10260: bound the PTR name walk to the RDATA, not the whole message
danielinux Aug 21, 2026
f21c6da
F-9366: fix http_request.query comment to cover non-GET requests
danielinux Aug 21, 2026
8ac7717
F-6475: prove the IGMP anti-disclosure guards are actually tested
danielinux Aug 21, 2026
9ffc674
F-8521: record the alignment-induced head wrap in fifo_push
danielinux Aug 21, 2026
c268ae1
F-10280: scope the udp_try_recv DHCP relaxation to the DHCP socket
danielinux Aug 21, 2026
e275c35
F-10281: validate bound_local_ip for non-SYN segments to a bound list…
danielinux Aug 21, 2026
ead1ca0
F-6471: remove dead UDP datagram length re-check in udp_try_recv
danielinux Aug 21, 2026
49cedb0
F-9374: document ssh_server_get_uptime as a placeholder
danielinux Aug 21, 2026
c10690d
F-9380: correct TFTP worst-case request-size comment for timeout
danielinux Aug 21, 2026
2ad91d7
F-6211: detect DNS responses by the QR bit alone
danielinux Aug 21, 2026
f0e57b2
F-8523: key the handle_socket_callbacks reap on socket identity
danielinux Aug 21, 2026
c977ef9
F-8525: reject oversized raw-socket payloads before narrowing len
danielinux Aug 21, 2026
303d73f
DEBUG: unbuffered trace prints for macOS test-wolfssl hang (temporary)
danielinux Aug 21, 2026
894fa5c
DEBUG: fix stdio include; add TXgate/flush/EAGAIN-FIFO-state prints (…
danielinux Aug 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/http/httpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct httpd;
struct http_request {
char method[HTTP_METHOD_LEN]; // "GET", "POST", etc.
char path[HTTP_PATH_LEN]; // URL path
char query[HTTP_QUERY_LEN]; // URL query string (for GET requests)
char query[HTTP_QUERY_LEN]; // URL query string, if present in the target
char headers[HTTP_HEADERS_LEN]; // HTTP headers
char body[HTTP_BODY_LEN]; // HTTP body (for POST requests)
size_t body_len;
Expand Down
4 changes: 3 additions & 1 deletion src/port/stm32h563/ssh_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ int ssh_server_init(struct wolfIP *stack, uint16_t port, ssh_debug_cb debug);
* Returns 0 on success */
int ssh_server_poll(void);

/* Get SSH server uptime in seconds (for status display) */
/* Get SSH server uptime in seconds (for status display).
* Currently a placeholder: returns 0 until a main-loop tick source is
* integrated, so the "uptime" SSH command always reports zero. */
uint32_t ssh_server_get_uptime(void);

#endif /* SSH_SERVER_H */
14 changes: 14 additions & 0 deletions src/test/test_native_wolfssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ int wolfSSL_SetIO_wolfIP_CTX(WOLFSSL_CTX *ctx, struct wolfIP *s);
static void server_cb(int fd, uint16_t event, void *arg)
{
int ret = 0;
printf("dbg cb: fd=0x%04x ev=0x%04x client_fd=0x%04x\n",
(unsigned)fd, (unsigned)event, (unsigned)client_fd);
fflush(stdout);
if ((fd == listen_fd) && (event & CB_EVENT_READABLE) && (client_fd == -1)) {
client_fd = wolfIP_sock_accept((struct wolfIP *)arg, listen_fd, NULL, NULL);
if (client_fd > 0) {
Expand Down Expand Up @@ -144,6 +147,8 @@ static void server_cb(int fd, uint16_t event, void *arg)
/* wolfIP side: main loop of the stack under test. */
static int test_loop(struct wolfIP *s, int active_close)
{
long last_beat = 0;
int dbg_n = 0;
exit_ok = 0;
exit_count = 0;
tot_sent = 0;
Expand All @@ -156,6 +161,14 @@ static int test_loop(struct wolfIP *s, int active_close)
gettimeofday(&tv, NULL);
ms_next = wolfIP_poll(s, tv.tv_sec * 1000 + tv.tv_usec / 1000);
usleep(ms_next * 1000);
gettimeofday(&tv, NULL);
dbg_n++;
if (tv.tv_sec - last_beat >= 2) {
last_beat = tv.tv_sec;
printf("dbg loop: n=%d ms_next=%u exit_ok=%d\n",
dbg_n, (unsigned)ms_next, exit_ok);
fflush(stdout);
}
if (exit_ok > 0) {
if (exit_count++ < 10)
continue;
Expand Down Expand Up @@ -415,6 +428,7 @@ int main(int argc, char **argv)

wolfSSL_Init();
wolfSSL_Debugging_OFF();
setvbuf(stdout, NULL, _IONBF, 0); /* DEBUG: unbuffered for CI logs */

(void)argc;
(void)argv;
Expand Down
15 changes: 15 additions & 0 deletions src/test/unit/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ Suite *wolf_suite(void)
tcase_add_test(tc_core, test_fifo_wrap_full_pop_then_refill_keeps_order_without_drops);
tcase_add_test(tc_core, test_fifo_wrap_flag_transitions_push_pop_around_boundary);
tcase_add_test(tc_core, test_fifo_wrap_flag_repeated_flips_keep_data_consistent);
tcase_add_test(tc_core, test_fifo_push_align_wrap_tail0_rejects_not_clobbers);
tcase_add_test(tc_core, test_fifo_push_align_wrap_keeps_nonempty_state);
tcase_add_test(tc_core, test_fifo_wrap_flag_transitions_with_odd_payload_sizes);
tcase_add_test(tc_core, test_fifo_wrap_flag_repeated_flips_with_odd_payload_sizes);

Expand Down Expand Up @@ -649,6 +651,7 @@ Suite *wolf_suite(void)
tcase_add_test(tc_utils, test_tcp_fin_wait_1_to_closing);
tcase_add_test(tc_utils, test_tcp_last_ack_closes_socket);
tcase_add_test(tc_utils, test_tcp_last_ack_closes_socket_delivers_closed_event);
tcase_add_test(tc_utils, test_handle_socket_callbacks_keeps_recreated_socket);
tcase_add_test(tc_utils, test_tcp_last_ack_partial_ack_keeps_socket_and_timer);
tcase_add_test(tc_utils, test_tcp_ack_acks_data_and_sets_writable);
tcase_add_test(tc_utils, test_tcp_ack_duplicate_resend_clears_sent);
Expand Down Expand Up @@ -851,6 +854,7 @@ Suite *wolf_suite(void)
tcase_add_test(tc_proto, test_raw_socket_send_hdrincl_respected);
tcase_add_test(tc_proto, test_raw_socket_send_builds_ip_header);
tcase_add_test(tc_proto, test_regression_raw_socket_send_ip_id_network_byte_order);
tcase_add_test(tc_proto, test_regression_raw_socket_tx_eagain_keeps_descriptor);
tcase_add_test(tc_proto, test_raw_socket_sendto_short_addrlen_returns_einval);
tcase_add_test(tc_proto, test_raw_socket_sendto_wrong_family_returns_einval);
tcase_add_test(tc_proto, test_raw_socket_sendto_payload_too_large_for_ip_header_returns_einval);
Expand All @@ -860,6 +864,7 @@ Suite *wolf_suite(void)
tcase_add_test(tc_proto, test_getsockopt_unsupported_option_returns_einval);
tcase_add_test(tc_proto, test_packet_socket_recv_frame);
tcase_add_test(tc_proto, test_packet_socket_send_frame);
tcase_add_test(tc_proto, test_regression_packet_socket_tx_eagain_keeps_descriptor);
#if WOLFIP_PACKET_SOCKETS
tcase_add_test(tc_proto, test_packet_socket_tx_filter_block_does_not_resend);
#endif
Expand Down Expand Up @@ -921,6 +926,7 @@ Suite *wolf_suite(void)
tcase_add_test(tc_proto, test_regression_icmp_echo_request_non_local_dst_no_reply);
tcase_add_test(tc_proto, test_tcp_listen_rejects_wrong_interface);
tcase_add_test(tc_proto, test_tcp_listen_accepts_bound_interface);
tcase_add_test(tc_proto, test_tcp_listen_requires_matching_local_ip);
tcase_add_test(tc_proto, test_tcp_listen_accepts_any_interface);
tcase_add_test(tc_proto, test_sock_connect_selects_local_ip_multi_if);
tcase_add_test(tc_proto, test_icmp_socket_send_recv);
Expand Down Expand Up @@ -974,6 +980,7 @@ Suite *wolf_suite(void)
tcase_add_test(tc_proto, test_regression_udp_len_exceeds_ip_len_dropped);
tcase_add_test(tc_proto, test_regression_udp_len_below_header_discards_and_unblocks);
tcase_add_test(tc_proto, test_regression_udp_payload_exceeds_buffer_discards_and_unblocks);
tcase_add_test(tc_proto, test_udp_dhcp_relaxation_scoped_to_dhcp_socket);
tcase_add_test(tc_proto, test_regression_icmp_payload_exceeds_buffer_discards_and_unblocks);
tcase_add_test(tc_proto, test_regression_tcp_ip_len_below_ip_header);
tcase_add_test(tc_proto, test_regression_syn_on_established_not_silently_processed);
Expand Down Expand Up @@ -1148,6 +1155,9 @@ Suite *wolf_suite(void)
tcase_add_test(tc_core, test_icmp_input_echo_reply_path_filter_at_eth);
tcase_add_test(tc_core, test_ip_recv_with_options_oversize_dropped);
tcase_add_test(tc_core, test_wolfip_recv_on_null_stack_returns);
#if WOLFIP_RAWSOCKETS
tcase_add_test(tc_core, test_raw_sendto_rejects_oversized_len_before_narrowing);
#endif

/* Socket API arms: TCP, RAW, PACKET */
tcase_add_test(tc_core, test_register_callback_tcp_stores_handle);
Expand Down Expand Up @@ -1360,9 +1370,11 @@ Suite *wolf_suite(void)
tcase_add_test(tc_core, test_poll_udp_socket_callback_dispatched);
#if WOLFIP_RAWSOCKETS
tcase_add_test(tc_core, test_poll_raw_socket_callback_dispatched);
tcase_add_test(tc_core, test_poll_raw_socket_callback_reraised_event_survives);
#endif /* WOLFIP_RAWSOCKETS */
#if WOLFIP_PACKET_SOCKETS
tcase_add_test(tc_core, test_poll_packet_socket_callback_dispatched);
tcase_add_test(tc_core, test_poll_packet_socket_callback_reraised_event_survives);
#endif /* WOLFIP_PACKET_SOCKETS */
tcase_add_test(tc_core, test_poll_tx_tcp_pkt_flag_sent_desc_skipped);
tcase_add_test(tc_core, test_poll_tx_tcp_arp_miss_emits_arp_request);
Expand Down Expand Up @@ -1529,6 +1541,7 @@ Suite *wolf_suite(void)
tcase_add_test(tc_core, test_dns_callback_rcode_nonzero_aborts_query);
tcase_add_test(tc_core, test_dns_callback_zero_ancount_no_delivery);
tcase_add_test(tc_core, test_dns_callback_aaaa_answer_skipped_for_a_query);
tcase_add_test(tc_core, test_dns_callback_qr_without_rd_is_accepted);
tcase_add_test(tc_core, test_dns_callback_rr_rdlen_truncated_aborts_query);
tcase_add_test(tc_core, test_dns_callback_bad_question_name_aborts_query);
tcase_add_test(tc_core, test_dns_callback_answer_forward_ptr_aborts_query);
Expand All @@ -1546,6 +1559,8 @@ Suite *wolf_suite(void)
tcase_add_test(tc_core, test_dns_skip_name_label_past_end);
tcase_add_test(tc_core, test_dns_copy_name_second_label_separator_and_label_fit);
tcase_add_test(tc_core, test_dns_callback_ptr_bad_copy_name_stays_pending);
tcase_add_test(tc_core, test_dns_callback_ptr_name_beyond_rdata_rejected);
tcase_add_test(tc_core, test_dns_callback_ptr_rdata_ends_in_pointer_ok);
tcase_add_test(tc_core, test_dns_copy_name_jumped_no_pos_increment);
tcase_add_test(tc_core, test_dns_send_query_socket_alloc_failure);
/* --- unit_tests_misc_edges.c (75 tests) --- */
Expand Down
6 changes: 3 additions & 3 deletions src/test/unit/unit_tests_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,14 +1098,14 @@ START_TEST(test_dns_skip_and_copy_name)
ret = dns_skip_name(buf, sizeof(buf), 0);
ck_assert_int_eq(ret, pos);

ret = dns_copy_name(buf, sizeof(buf), 0, out, sizeof(out));
ret = dns_copy_name(buf, sizeof(buf), 0, out, sizeof(out), sizeof(buf));
ck_assert_int_eq(ret, 0);
ck_assert_str_eq(out, "www.example.com");

/* add a pointer to the name at offset 0 */
buf[pos++] = 0xC0;
buf[pos++] = 0x00;
ret = dns_copy_name(buf, sizeof(buf), pos - 2, out, sizeof(out));
ret = dns_copy_name(buf, sizeof(buf), pos - 2, out, sizeof(out), sizeof(buf));
ck_assert_int_eq(ret, 0);
ck_assert_str_eq(out, "www.example.com");

Expand All @@ -1115,7 +1115,7 @@ START_TEST(test_dns_skip_and_copy_name)
buf[pos++] = (uint8_t)(ptr_pos + 2);
buf[pos++] = 3; memcpy(&buf[pos], "bad", 3); pos += 3;
buf[pos++] = 0;
ret = dns_copy_name(buf, pos, ptr_pos, out, sizeof(out));
ret = dns_copy_name(buf, pos, ptr_pos, out, sizeof(out), pos);
ck_assert_int_eq(ret, -1);
}
END_TEST
Expand Down
34 changes: 34 additions & 0 deletions src/test/unit/unit_tests_branches.c
Original file line number Diff line number Diff line change
Expand Up @@ -2607,3 +2607,37 @@ START_TEST(test_wolfip_recv_on_null_stack_returns)
wolfIP_recv_on(NULL, TEST_PRIMARY_IF, buf, sizeof(buf));
}
END_TEST

#if WOLFIP_RAWSOCKETS
/* F-8525: the raw-socket sendto path must reject a payload that cannot fit
* in a frame before narrowing len to uint32_t. A size_t len above the
* LINK_MTU-derived bound wraps in the total_len computation, slips past the
* LINK_MTU guard, and lets the payload memcpy overflow the fixed-size frame
* buffer. len = UINT32_MAX + 100 narrows to 100 (which would pass the MTU
* guard) but must be rejected before any memcpy. The overflow itself cannot
* be exercised in a unit test (it needs a >4GB buffer), so this pins the
* new size_t bound: the oversized length is refused, not narrowed. */
START_TEST(test_raw_sendto_rejects_oversized_len_before_narrowing)
{
struct wolfIP s;
int fd;
uint8_t buf[8];
struct wolfIP_sockaddr_in sin;

wolfIP_init(&s);
mock_link_init(&s);
wolfIP_ipconfig_set(&s, 0x0A000001U, 0xFFFFFF00U, 0);

fd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_RAW, 0);
ck_assert_int_ge(fd, 0);

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ee32(0x0A000002U);

ck_assert_int_eq(wolfIP_sock_sendto(&s, fd, buf, (size_t)UINT32_MAX + 100, 0,
(struct wolfIP_sockaddr *)&sin, sizeof(sin)), -WOLFIP_EINVAL);
}
END_TEST
#endif /* WOLFIP_RAWSOCKETS */

4 changes: 4 additions & 0 deletions src/test/unit/unit_tests_dns_dhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -6457,6 +6457,10 @@ START_TEST(test_udp_try_recv_dhcp_running_local_zero)
ck_assert_ptr_nonnull(ts);
ts->src_port = 1234;
ts->local_ip = 0;
/* F-10280: the local_ip==0 relaxation is scoped to the DHCP client
* socket, so this socket must be the DHCP socket to receive before it
* owns an address. */
s.dhcp_udp_sd = (int)(MARK_UDP_SOCKET | (uint32_t)(ts - s.udpsockets));

memset(udp_buf, 0, sizeof(udp_buf));
udp->ip.dst = ee32(local_ip);
Expand Down
Loading
Loading