Skip to content

Commit 60444d8

Browse files
authored
Merge pull request #76 from danielinux/fixes-20260310
Fixes for DNS, TCP, ICMP
2 parents e87df72 + bf7f39e commit 60444d8

2 files changed

Lines changed: 365 additions & 31 deletions

File tree

src/test/unit/unit.c

Lines changed: 302 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2092,6 +2092,7 @@ START_TEST(test_sock_bind_icmp_success)
20922092

20932093
ck_assert_int_eq(wolfIP_sock_bind(&s, icmp_sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin)), 0);
20942094
ck_assert_uint_eq(ts->src_port, 7U);
2095+
ck_assert_uint_eq(ts->bound_local_ip, 0x0A000001U);
20952096
}
20962097
END_TEST
20972098

@@ -2255,7 +2256,7 @@ START_TEST(test_dns_query_and_callback_a)
22552256

22562257
dns_callback(s.dns_udp_sd, CB_EVENT_READABLE, &s);
22572258
ck_assert_int_eq(dns_lookup_calls, 1);
2258-
ck_assert_uint_eq(dns_lookup_ip, ee32(0x0A000042U));
2259+
ck_assert_uint_eq(dns_lookup_ip, 0x0A000042U);
22592260
ck_assert_int_eq(s.dns_id, 0);
22602261
ck_assert_int_eq(s.dns_query_type, DNS_QUERY_TYPE_NONE);
22612262
}
@@ -2741,6 +2742,33 @@ START_TEST(test_sock_connect_icmp_primary_ip_fallback)
27412742
}
27422743
END_TEST
27432744

2745+
START_TEST(test_sock_connect_icmp_bound_local_ip_match)
2746+
{
2747+
struct wolfIP s;
2748+
const ip4 primary_ip = 0xC0A80009U;
2749+
const ip4 secondary_ip = 0xC0A80109U;
2750+
const ip4 remote_secondary = 0xC0A801A1U;
2751+
int icmp_sd;
2752+
struct tsocket *ts;
2753+
struct wolfIP_sockaddr_in sin;
2754+
2755+
setup_stack_with_two_ifaces(&s, primary_ip, secondary_ip);
2756+
2757+
icmp_sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_ICMP);
2758+
ck_assert_int_gt(icmp_sd, 0);
2759+
ts = &s.icmpsockets[SOCKET_UNMARK(icmp_sd)];
2760+
ts->bound_local_ip = primary_ip;
2761+
2762+
memset(&sin, 0, sizeof(sin));
2763+
sin.sin_family = AF_INET;
2764+
sin.sin_addr.s_addr = ee32(remote_secondary);
2765+
2766+
ck_assert_int_eq(wolfIP_sock_connect(&s, icmp_sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin)), 0);
2767+
ck_assert_uint_eq(ts->local_ip, primary_ip);
2768+
ck_assert_uint_eq(ts->if_idx, TEST_PRIMARY_IF);
2769+
}
2770+
END_TEST
2771+
27442772
START_TEST(test_sock_connect_tcp_established_returns_zero)
27452773
{
27462774
struct wolfIP s;
@@ -7765,6 +7793,136 @@ START_TEST(test_dns_callback_short_header_ignored)
77657793
}
77667794
END_TEST
77677795

7796+
START_TEST(test_dns_callback_wrong_id_ignored)
7797+
{
7798+
struct wolfIP s;
7799+
uint8_t response[128];
7800+
int pos;
7801+
struct dns_header *hdr = (struct dns_header *)response;
7802+
struct dns_question *q;
7803+
struct dns_rr *rr;
7804+
const uint8_t ip_bytes[4] = {0x0A, 0x00, 0x00, 0x42};
7805+
7806+
wolfIP_init(&s);
7807+
mock_link_init(&s);
7808+
s.dns_server = 0x0A000001U;
7809+
s.dns_query_type = DNS_QUERY_TYPE_A;
7810+
s.dns_id = 0x1234;
7811+
s.dns_lookup_cb = test_dns_lookup_cb;
7812+
dns_lookup_calls = 0;
7813+
dns_lookup_ip = 0;
7814+
s.dns_udp_sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
7815+
ck_assert_int_gt(s.dns_udp_sd, 0);
7816+
7817+
memset(response, 0, sizeof(response));
7818+
hdr->id = ee16(0x4321);
7819+
hdr->flags = ee16(0x8100);
7820+
hdr->qdcount = ee16(1);
7821+
hdr->ancount = ee16(1);
7822+
pos = sizeof(struct dns_header);
7823+
response[pos++] = 7; memcpy(&response[pos], "example", 7); pos += 7;
7824+
response[pos++] = 3; memcpy(&response[pos], "com", 3); pos += 3;
7825+
response[pos++] = 0;
7826+
q = (struct dns_question *)(response + pos);
7827+
q->qtype = ee16(DNS_A);
7828+
q->qclass = ee16(1);
7829+
pos += sizeof(struct dns_question);
7830+
response[pos++] = 0xC0;
7831+
response[pos++] = (uint8_t)sizeof(struct dns_header);
7832+
rr = (struct dns_rr *)(response + pos);
7833+
rr->type = ee16(DNS_A);
7834+
rr->class = ee16(1);
7835+
rr->ttl = ee32(60);
7836+
rr->rdlength = ee16(4);
7837+
pos += sizeof(struct dns_rr);
7838+
memcpy(&response[pos], ip_bytes, sizeof(ip_bytes));
7839+
pos += sizeof(ip_bytes);
7840+
7841+
enqueue_udp_rx(&s.udpsockets[SOCKET_UNMARK(s.dns_udp_sd)], response, (uint16_t)pos, DNS_PORT);
7842+
dns_callback(s.dns_udp_sd, CB_EVENT_READABLE, &s);
7843+
ck_assert_int_eq(dns_lookup_calls, 0);
7844+
ck_assert_uint_eq(dns_lookup_ip, 0U);
7845+
ck_assert_uint_eq(s.dns_id, 0x1234);
7846+
ck_assert_int_eq(s.dns_query_type, DNS_QUERY_TYPE_A);
7847+
}
7848+
END_TEST
7849+
7850+
START_TEST(test_dns_callback_abort_clears_query_state)
7851+
{
7852+
struct wolfIP s;
7853+
uint8_t bad_response[64];
7854+
uint8_t good_response[128];
7855+
int pos;
7856+
struct dns_header *hdr = (struct dns_header *)bad_response;
7857+
struct dns_header *good_hdr = (struct dns_header *)good_response;
7858+
struct dns_question *q;
7859+
struct dns_rr *rr;
7860+
const uint8_t ip_bytes[4] = {0x0A, 0x00, 0x00, 0x42};
7861+
7862+
wolfIP_init(&s);
7863+
mock_link_init(&s);
7864+
s.dns_server = 0x0A000001U;
7865+
s.dns_query_type = DNS_QUERY_TYPE_A;
7866+
s.dns_id = 0x1234;
7867+
s.dns_lookup_cb = test_dns_lookup_cb;
7868+
dns_lookup_calls = 0;
7869+
dns_lookup_ip = 0;
7870+
s.dns_udp_sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
7871+
ck_assert_int_gt(s.dns_udp_sd, 0);
7872+
7873+
memset(bad_response, 0, sizeof(bad_response));
7874+
hdr->id = ee16(s.dns_id);
7875+
hdr->flags = ee16(0x8100);
7876+
hdr->qdcount = ee16(1);
7877+
hdr->ancount = ee16(0);
7878+
pos = sizeof(struct dns_header);
7879+
bad_response[pos++] = 60;
7880+
memset(&bad_response[pos], 'a', 5);
7881+
pos += 5;
7882+
7883+
enqueue_udp_rx(&s.udpsockets[SOCKET_UNMARK(s.dns_udp_sd)], bad_response, (uint16_t)pos, DNS_PORT);
7884+
dns_callback(s.dns_udp_sd, CB_EVENT_READABLE, &s);
7885+
ck_assert_uint_eq(s.dns_id, 0);
7886+
7887+
memset(good_response, 0, sizeof(good_response));
7888+
good_hdr->id = 0;
7889+
good_hdr->flags = ee16(0x8100);
7890+
good_hdr->qdcount = ee16(1);
7891+
good_hdr->ancount = ee16(1);
7892+
pos = sizeof(struct dns_header);
7893+
good_response[pos++] = 7; memcpy(&good_response[pos], "example", 7); pos += 7;
7894+
good_response[pos++] = 3; memcpy(&good_response[pos], "com", 3); pos += 3;
7895+
good_response[pos++] = 0;
7896+
q = (struct dns_question *)(good_response + pos);
7897+
q->qtype = ee16(DNS_A);
7898+
q->qclass = ee16(1);
7899+
pos += sizeof(struct dns_question);
7900+
good_response[pos++] = 0xC0;
7901+
good_response[pos++] = (uint8_t)sizeof(struct dns_header);
7902+
rr = (struct dns_rr *)(good_response + pos);
7903+
rr->type = ee16(DNS_A);
7904+
rr->class = ee16(1);
7905+
rr->ttl = ee32(60);
7906+
rr->rdlength = ee16(4);
7907+
pos += sizeof(struct dns_rr);
7908+
memcpy(&good_response[pos], ip_bytes, sizeof(ip_bytes));
7909+
pos += sizeof(ip_bytes);
7910+
7911+
enqueue_udp_rx(&s.udpsockets[SOCKET_UNMARK(s.dns_udp_sd)], good_response, (uint16_t)pos, DNS_PORT);
7912+
dns_callback(s.dns_udp_sd, CB_EVENT_READABLE, &s);
7913+
ck_assert_int_eq(dns_lookup_calls, 0);
7914+
ck_assert_uint_eq(dns_lookup_ip, 0U);
7915+
ck_assert_int_eq(s.dns_query_type, DNS_QUERY_TYPE_NONE);
7916+
ck_assert_ptr_eq(s.dns_lookup_cb, NULL);
7917+
}
7918+
END_TEST
7919+
7920+
START_TEST(test_dns_abort_query_null_noop)
7921+
{
7922+
dns_abort_query(NULL);
7923+
}
7924+
END_TEST
7925+
77687926
START_TEST(test_tcp_input_ttl_zero_sends_icmp)
77697927
{
77707928
struct wolfIP s;
@@ -14311,6 +14469,48 @@ START_TEST(test_tcp_ack_coarse_rtt_sets_writable)
1431114469
}
1431214470
END_TEST
1431314471

14472+
START_TEST(test_tcp_ack_coarse_rtt_across_low32_wrap)
14473+
{
14474+
struct wolfIP s;
14475+
struct tsocket *ts;
14476+
struct tcp_seg_buf segbuf;
14477+
struct wolfIP_tcp_seg *seg;
14478+
struct wolfIP_tcp_seg ackseg;
14479+
struct pkt_desc *desc;
14480+
14481+
wolfIP_init(&s);
14482+
ts = &s.tcpsockets[0];
14483+
memset(ts, 0, sizeof(*ts));
14484+
ts->proto = WI_IPPROTO_TCP;
14485+
ts->S = &s;
14486+
ts->sock.tcp.state = TCP_ESTABLISHED;
14487+
ts->sock.tcp.cwnd = TCP_MSS;
14488+
ts->sock.tcp.ssthresh = TCP_MSS * 4;
14489+
fifo_init(&ts->sock.tcp.txbuf, ts->txmem, TXBUF_SIZE);
14490+
s.last_tick = (1ULL << 32) + 100U;
14491+
14492+
memset(&segbuf, 0, sizeof(segbuf));
14493+
seg = &segbuf.seg;
14494+
seg->ip.len = ee16(IP_HEADER_LEN + TCP_HEADER_LEN + 1);
14495+
seg->hlen = TCP_HEADER_LEN << 2;
14496+
seg->seq = ee32(100);
14497+
ck_assert_int_eq(fifo_push(&ts->sock.tcp.txbuf, &segbuf, sizeof(segbuf)), 0);
14498+
desc = fifo_peek(&ts->sock.tcp.txbuf);
14499+
ck_assert_ptr_nonnull(desc);
14500+
desc->flags |= PKT_FLAG_SENT;
14501+
desc->time_sent = 0xFFFFFFF0U;
14502+
14503+
memset(&ackseg, 0, sizeof(ackseg));
14504+
ackseg.ack = ee32(101);
14505+
ackseg.hlen = TCP_HEADER_LEN << 2;
14506+
ackseg.flags = TCP_FLAG_ACK;
14507+
14508+
tcp_ack(ts, &ackseg);
14509+
ck_assert_uint_eq(ts->sock.tcp.rtt, 116U);
14510+
ck_assert_uint_eq(ts->events & CB_EVENT_WRITABLE, CB_EVENT_WRITABLE);
14511+
}
14512+
END_TEST
14513+
1431414514
START_TEST(test_tcp_ack_duplicate_clears_sent_large_seg_len)
1431514515
{
1431614516
struct wolfIP s;
@@ -15292,6 +15492,68 @@ START_TEST(test_tcp_input_established_ack_only_returns)
1529215492
}
1529315493
END_TEST
1529415494

15495+
START_TEST(test_tcp_input_close_wait_processes_ack)
15496+
{
15497+
struct wolfIP s;
15498+
struct tsocket *ts;
15499+
struct tcp_seg_buf segbuf;
15500+
struct wolfIP_tcp_seg *queued;
15501+
struct wolfIP_tcp_seg ackseg;
15502+
struct pkt_desc *desc;
15503+
15504+
wolfIP_init(&s);
15505+
mock_link_init(&s);
15506+
wolfIP_ipconfig_set(&s, 0x0A000001U, 0xFFFFFF00U, 0);
15507+
15508+
ts = &s.tcpsockets[0];
15509+
memset(ts, 0, sizeof(*ts));
15510+
ts->proto = WI_IPPROTO_TCP;
15511+
ts->S = &s;
15512+
ts->sock.tcp.state = TCP_CLOSE_WAIT;
15513+
ts->src_port = 1234;
15514+
ts->dst_port = 4321;
15515+
ts->local_ip = 0x0A000001U;
15516+
ts->remote_ip = 0x0A000002U;
15517+
ts->sock.tcp.snd_una = 100;
15518+
ts->sock.tcp.seq = 101;
15519+
ts->sock.tcp.bytes_in_flight = 1;
15520+
fifo_init(&ts->sock.tcp.txbuf, ts->txmem, TXBUF_SIZE);
15521+
15522+
memset(&segbuf, 0, sizeof(segbuf));
15523+
queued = &segbuf.seg;
15524+
queued->ip.len = ee16(IP_HEADER_LEN + TCP_HEADER_LEN + 1);
15525+
queued->hlen = TCP_HEADER_LEN << 2;
15526+
queued->seq = ee32(100);
15527+
ck_assert_int_eq(fifo_push(&ts->sock.tcp.txbuf, &segbuf, sizeof(segbuf)), 0);
15528+
desc = fifo_peek(&ts->sock.tcp.txbuf);
15529+
ck_assert_ptr_nonnull(desc);
15530+
desc->flags |= PKT_FLAG_SENT;
15531+
15532+
memset(&ackseg, 0, sizeof(ackseg));
15533+
ackseg.ip.ver_ihl = 0x45;
15534+
ackseg.ip.ttl = 64;
15535+
ackseg.ip.proto = WI_IPPROTO_TCP;
15536+
ackseg.ip.len = ee16(IP_HEADER_LEN + TCP_HEADER_LEN);
15537+
ackseg.ip.src = ee32(ts->remote_ip);
15538+
ackseg.ip.dst = ee32(ts->local_ip);
15539+
ackseg.src_port = ee16(ts->dst_port);
15540+
ackseg.dst_port = ee16(ts->src_port);
15541+
ackseg.hlen = TCP_HEADER_LEN << 2;
15542+
ackseg.flags = TCP_FLAG_ACK;
15543+
ackseg.ack = ee32(101);
15544+
ackseg.win = ee16(32);
15545+
fix_tcp_checksums(&ackseg);
15546+
15547+
tcp_input(&s, TEST_PRIMARY_IF, &ackseg,
15548+
(uint32_t)(ETH_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN));
15549+
15550+
ck_assert_int_eq(ts->sock.tcp.state, TCP_CLOSE_WAIT);
15551+
ck_assert_uint_eq(ts->sock.tcp.snd_una, 101U);
15552+
ck_assert_uint_eq(ts->sock.tcp.bytes_in_flight, 0U);
15553+
ck_assert_ptr_eq(fifo_peek(&ts->sock.tcp.txbuf), NULL);
15554+
}
15555+
END_TEST
15556+
1529515557
START_TEST(test_tcp_sock_close_state_transitions)
1529615558
{
1529715559
struct wolfIP s;
@@ -18003,6 +18265,38 @@ START_TEST(test_icmp_socket_send_recv)
1800318265
}
1800418266
END_TEST
1800518267

18268+
START_TEST(test_icmp_sendto_respects_bound_local_ip_interface)
18269+
{
18270+
struct wolfIP s;
18271+
const ip4 primary_ip = 0xC0A80009U;
18272+
const ip4 secondary_ip = 0xC0A80109U;
18273+
const ip4 remote_secondary = 0xC0A801A1U;
18274+
int sd;
18275+
struct tsocket *ts;
18276+
struct wolfIP_sockaddr_in sin;
18277+
uint8_t payload[ICMP_HEADER_LEN] = {0};
18278+
18279+
setup_stack_with_two_ifaces(&s, primary_ip, secondary_ip);
18280+
18281+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_ICMP);
18282+
ck_assert_int_gt(sd, 0);
18283+
ts = &s.icmpsockets[SOCKET_UNMARK(sd)];
18284+
fifo_init(&ts->sock.udp.txbuf, ts->txmem, TXBUF_SIZE);
18285+
ts->bound_local_ip = primary_ip;
18286+
18287+
memset(&sin, 0, sizeof(sin));
18288+
sin.sin_family = AF_INET;
18289+
sin.sin_addr.s_addr = ee32(remote_secondary);
18290+
18291+
payload[0] = ICMP_ECHO_REQUEST;
18292+
18293+
ck_assert_int_eq(wolfIP_sock_sendto(&s, sd, payload, sizeof(payload), 0,
18294+
(struct wolfIP_sockaddr *)&sin, sizeof(sin)), (int)sizeof(payload));
18295+
ck_assert_uint_eq(ts->local_ip, primary_ip);
18296+
ck_assert_uint_eq(ts->if_idx, TEST_PRIMARY_IF);
18297+
}
18298+
END_TEST
18299+
1800618300
START_TEST(test_regression_snd_una_initialized_on_syn_rcvd)
1800718301
{
1800818302
struct wolfIP s;
@@ -18498,6 +18792,7 @@ Suite *wolf_suite(void)
1849818792
tcase_add_test(tc_utils, test_sock_connect_udp_bound_local_ip_no_match);
1849918793
tcase_add_test(tc_utils, test_sock_connect_udp_bound_local_ip_match);
1850018794
tcase_add_test(tc_utils, test_sock_connect_icmp_sets_local_ip_from_conf);
18795+
tcase_add_test(tc_utils, test_sock_connect_icmp_bound_local_ip_match);
1850118796
tcase_add_test(tc_utils, test_sock_connect_icmp_wrong_family);
1850218797
tcase_add_test(tc_utils, test_sock_connect_icmp_local_ip_pre_set);
1850318798
tcase_add_test(tc_utils, test_sock_connect_icmp_conf_null);
@@ -18630,6 +18925,9 @@ Suite *wolf_suite(void)
1863018925
tcase_add_test(tc_utils, test_dns_callback_bad_flags);
1863118926
tcase_add_test(tc_utils, test_dns_callback_bad_name);
1863218927
tcase_add_test(tc_utils, test_dns_callback_short_header_ignored);
18928+
tcase_add_test(tc_utils, test_dns_callback_wrong_id_ignored);
18929+
tcase_add_test(tc_utils, test_dns_callback_abort_clears_query_state);
18930+
tcase_add_test(tc_utils, test_dns_abort_query_null_noop);
1863318931
tcase_add_test(tc_utils, test_tcp_input_ttl_zero_sends_icmp);
1863418932
tcase_add_test(tc_utils, test_dns_callback_bad_rr_rdlen);
1863518933
tcase_add_test(tc_utils, test_dhcp_parse_offer_no_match);
@@ -18716,6 +19014,7 @@ Suite *wolf_suite(void)
1871619014
tcase_add_test(tc_utils, test_tcp_input_port_mismatch_skips_socket);
1871719015
tcase_add_test(tc_utils, test_tcp_input_syn_bound_ip_mismatch);
1871819016
tcase_add_test(tc_utils, test_tcp_input_syn_rcvd_ack_wrong_flags);
19017+
tcase_add_test(tc_utils, test_tcp_input_close_wait_processes_ack);
1871919018
tcase_add_test(tc_utils, test_tcp_input_established_ack_only_returns);
1872019019
tcase_add_test(tc_utils, test_tcp_input_syn_dst_not_local);
1872119020
tcase_add_test(tc_utils, test_tcp_input_syn_dst_outside_subnet);
@@ -18746,6 +19045,7 @@ Suite *wolf_suite(void)
1874619045
tcase_add_test(tc_utils, test_tcp_ack_last_seq_not_last_ack_state);
1874719046
tcase_add_test(tc_utils, test_tcp_ack_no_progress_when_ack_far_ahead);
1874819047
tcase_add_test(tc_utils, test_tcp_ack_coarse_rtt_sets_writable);
19048+
tcase_add_test(tc_utils, test_tcp_ack_coarse_rtt_across_low32_wrap);
1874919049
tcase_add_test(tc_utils, test_tcp_ack_duplicate_clears_sent_large_seg_len);
1875019050
tcase_add_test(tc_utils, test_tcp_ack_duplicate_discards_zero_len_segment_far_ack);
1875119051
tcase_add_test(tc_utils, test_tcp_ack_duplicate_ssthresh_min);
@@ -18771,6 +19071,7 @@ Suite *wolf_suite(void)
1877119071
tcase_add_test(tc_utils, test_tcp_send_syn_advertises_sack_permitted);
1877219072
tcase_add_test(tc_utils, test_tcp_build_ack_options_does_not_write_past_returned_len);
1877319073
tcase_add_test(tc_utils, test_tcp_build_ack_options_omits_ts_when_not_negotiated);
19074+
tcase_add_test(tc_utils, test_icmp_sendto_respects_bound_local_ip_interface);
1877419075
tcase_add_test(tc_utils, test_tcp_sort_sack_blocks_swaps_out_of_order);
1877519076
tcase_add_test(tc_utils, test_tcp_sort_sack_blocks_wrap_order);
1877619077
tcase_add_test(tc_utils, test_tcp_merge_sack_blocks_adjacent_and_disjoint);

0 commit comments

Comments
 (0)