Skip to content

Commit bf7f39e

Browse files
committed
Addressed copilot's comments
1 parent 8abbfed commit bf7f39e

2 files changed

Lines changed: 236 additions & 28 deletions

File tree

src/test/unit/unit.c

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,6 +2742,33 @@ START_TEST(test_sock_connect_icmp_primary_ip_fallback)
27422742
}
27432743
END_TEST
27442744

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+
27452772
START_TEST(test_sock_connect_tcp_established_returns_zero)
27462773
{
27472774
struct wolfIP s;
@@ -7820,6 +7847,82 @@ START_TEST(test_dns_callback_wrong_id_ignored)
78207847
}
78217848
END_TEST
78227849

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+
78237926
START_TEST(test_tcp_input_ttl_zero_sends_icmp)
78247927
{
78257928
struct wolfIP s;
@@ -14366,6 +14469,48 @@ START_TEST(test_tcp_ack_coarse_rtt_sets_writable)
1436614469
}
1436714470
END_TEST
1436814471

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+
1436914514
START_TEST(test_tcp_ack_duplicate_clears_sent_large_seg_len)
1437014515
{
1437114516
struct wolfIP s;
@@ -18120,6 +18265,38 @@ START_TEST(test_icmp_socket_send_recv)
1812018265
}
1812118266
END_TEST
1812218267

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+
1812318300
START_TEST(test_regression_snd_una_initialized_on_syn_rcvd)
1812418301
{
1812518302
struct wolfIP s;
@@ -18615,6 +18792,7 @@ Suite *wolf_suite(void)
1861518792
tcase_add_test(tc_utils, test_sock_connect_udp_bound_local_ip_no_match);
1861618793
tcase_add_test(tc_utils, test_sock_connect_udp_bound_local_ip_match);
1861718794
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);
1861818796
tcase_add_test(tc_utils, test_sock_connect_icmp_wrong_family);
1861918797
tcase_add_test(tc_utils, test_sock_connect_icmp_local_ip_pre_set);
1862018798
tcase_add_test(tc_utils, test_sock_connect_icmp_conf_null);
@@ -18748,6 +18926,8 @@ Suite *wolf_suite(void)
1874818926
tcase_add_test(tc_utils, test_dns_callback_bad_name);
1874918927
tcase_add_test(tc_utils, test_dns_callback_short_header_ignored);
1875018928
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);
1875118931
tcase_add_test(tc_utils, test_tcp_input_ttl_zero_sends_icmp);
1875218932
tcase_add_test(tc_utils, test_dns_callback_bad_rr_rdlen);
1875318933
tcase_add_test(tc_utils, test_dhcp_parse_offer_no_match);
@@ -18865,6 +19045,7 @@ Suite *wolf_suite(void)
1886519045
tcase_add_test(tc_utils, test_tcp_ack_last_seq_not_last_ack_state);
1886619046
tcase_add_test(tc_utils, test_tcp_ack_no_progress_when_ack_far_ahead);
1886719047
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);
1886819049
tcase_add_test(tc_utils, test_tcp_ack_duplicate_clears_sent_large_seg_len);
1886919050
tcase_add_test(tc_utils, test_tcp_ack_duplicate_discards_zero_len_segment_far_ack);
1887019051
tcase_add_test(tc_utils, test_tcp_ack_duplicate_ssthresh_min);
@@ -18890,6 +19071,7 @@ Suite *wolf_suite(void)
1889019071
tcase_add_test(tc_utils, test_tcp_send_syn_advertises_sack_permitted);
1889119072
tcase_add_test(tc_utils, test_tcp_build_ack_options_does_not_write_past_returned_len);
1889219073
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);
1889319075
tcase_add_test(tc_utils, test_tcp_sort_sack_blocks_swaps_out_of_order);
1889419076
tcase_add_test(tc_utils, test_tcp_sort_sack_blocks_wrap_order);
1889519077
tcase_add_test(tc_utils, test_tcp_merge_sack_blocks_adjacent_and_disjoint);

src/wolfip.c

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3796,15 +3796,24 @@ int wolfIP_sock_connect(struct wolfIP *s, int sockfd, const struct wolfIP_sockad
37963796
if ((sin->sin_family != AF_INET) || (addrlen < sizeof(struct wolfIP_sockaddr_in)))
37973797
return -WOLFIP_EINVAL;
37983798
ts->remote_ip = ee32(sin->sin_addr.s_addr);
3799-
if_idx = wolfIP_route_for_ip(s, ts->remote_ip);
3800-
conf = wolfIP_ipconf_at(s, if_idx);
3801-
ts->if_idx = (uint8_t)if_idx;
3802-
if (ts->local_ip == 0 && conf && conf->ip != IPADDR_ANY)
3803-
ts->local_ip = conf->ip;
3804-
else if (ts->local_ip == 0) {
3805-
struct ipconf *primary = wolfIP_primary_ipconf(s);
3806-
if (primary && primary->ip != IPADDR_ANY)
3807-
ts->local_ip = primary->ip;
3799+
if (ts->bound_local_ip != IPADDR_ANY) {
3800+
int bound_match = 0;
3801+
unsigned int bound_if = wolfIP_if_for_local_ip(s, ts->bound_local_ip, &bound_match);
3802+
if (!bound_match)
3803+
return -WOLFIP_EINVAL;
3804+
ts->if_idx = (uint8_t)bound_if;
3805+
ts->local_ip = ts->bound_local_ip;
3806+
} else {
3807+
if_idx = wolfIP_route_for_ip(s, ts->remote_ip);
3808+
conf = wolfIP_ipconf_at(s, if_idx);
3809+
ts->if_idx = (uint8_t)if_idx;
3810+
if (ts->local_ip == 0 && conf && conf->ip != IPADDR_ANY)
3811+
ts->local_ip = conf->ip;
3812+
else if (ts->local_ip == 0) {
3813+
struct ipconf *primary = wolfIP_primary_ipconf(s);
3814+
if (primary && primary->ip != IPADDR_ANY)
3815+
ts->local_ip = primary->ip;
3816+
}
38083817
}
38093818
return 0;
38103819
}
@@ -4124,16 +4133,25 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len
41244133
if (ts->src_port == 0)
41254134
ts->src_port = 1;
41264135
}
4127-
if_idx = wolfIP_route_for_ip(s, ts->remote_ip);
4128-
conf = wolfIP_ipconf_at(s, if_idx);
4129-
ts->if_idx = (uint8_t)if_idx;
4130-
if (ts->local_ip == 0) {
4131-
if (conf && conf->ip != IPADDR_ANY)
4132-
ts->local_ip = conf->ip;
4133-
else {
4134-
struct ipconf *primary = wolfIP_primary_ipconf(s);
4135-
if (primary && primary->ip != IPADDR_ANY)
4136-
ts->local_ip = primary->ip;
4136+
if (ts->bound_local_ip != IPADDR_ANY) {
4137+
int bound_match = 0;
4138+
unsigned int bound_if = wolfIP_if_for_local_ip(s, ts->bound_local_ip, &bound_match);
4139+
if (!bound_match)
4140+
return -WOLFIP_EINVAL;
4141+
ts->if_idx = (uint8_t)bound_if;
4142+
ts->local_ip = ts->bound_local_ip;
4143+
} else {
4144+
if_idx = wolfIP_route_for_ip(s, ts->remote_ip);
4145+
conf = wolfIP_ipconf_at(s, if_idx);
4146+
ts->if_idx = (uint8_t)if_idx;
4147+
if (ts->local_ip == 0) {
4148+
if (conf && conf->ip != IPADDR_ANY)
4149+
ts->local_ip = conf->ip;
4150+
else {
4151+
struct ipconf *primary = wolfIP_primary_ipconf(s);
4152+
if (primary && primary->ip != IPADDR_ANY)
4153+
ts->local_ip = primary->ip;
4154+
}
41374155
}
41384156
}
41394157
if (sizeof(struct wolfIP_ip_packet) + payload_len > sizeof(frame))
@@ -5860,6 +5878,16 @@ static int dns_copy_name(const uint8_t *buf, int len, int offset, char *out,
58605878
return -1;
58615879
}
58625880

5881+
static void dns_abort_query(struct wolfIP *s)
5882+
{
5883+
if (!s)
5884+
return;
5885+
s->dns_id = 0;
5886+
s->dns_query_type = DNS_QUERY_TYPE_NONE;
5887+
s->dns_lookup_cb = NULL;
5888+
s->dns_ptr_cb = NULL;
5889+
}
5890+
58635891
void dns_callback(int dns_sd, uint16_t ev, void *arg)
58645892
{
58655893
struct wolfIP *s = (struct wolfIP *)arg;
@@ -5873,7 +5901,7 @@ void dns_callback(int dns_sd, uint16_t ev, void *arg)
58735901
if (dns_len < 0) {
58745902
wolfIP_sock_close(s, dns_sd);
58755903
s->dns_udp_sd = -1;
5876-
s->dns_id = 0;
5904+
dns_abort_query(s);
58775905
return;
58785906
}
58795907
if (dns_len < (int)sizeof(struct dns_header))
@@ -5888,7 +5916,7 @@ void dns_callback(int dns_sd, uint16_t ev, void *arg)
58885916
while (qcount-- > 0) {
58895917
pos = dns_skip_name((const uint8_t *)buf, dns_len, pos);
58905918
if (pos < 0 || pos + (int)sizeof(struct dns_question) > dns_len) {
5891-
s->dns_id = 0;
5919+
dns_abort_query(s);
58925920
return;
58935921
}
58945922
pos += sizeof(struct dns_question);
@@ -5898,20 +5926,20 @@ void dns_callback(int dns_sd, uint16_t ev, void *arg)
58985926
uint16_t rdlen;
58995927
pos = dns_skip_name((const uint8_t *)buf, dns_len, pos);
59005928
if (pos < 0 || pos + (int)sizeof(struct dns_rr) > dns_len) {
5901-
s->dns_id = 0;
5929+
dns_abort_query(s);
59025930
return;
59035931
}
59045932
rr = (struct dns_rr *)(buf + pos);
59055933
pos += sizeof(struct dns_rr);
59065934
rdlen = ee16(rr->rdlength);
59075935
if (pos + rdlen > dns_len) {
5908-
s->dns_id = 0;
5936+
dns_abort_query(s);
59095937
return;
59105938
}
59115939
if (s->dns_query_type == DNS_QUERY_TYPE_A && ee16(rr->type) == DNS_A && rdlen >= 4) {
59125940
uint32_t ip;
59135941
if (pos + 4 > dns_len) {
5914-
s->dns_id = 0;
5942+
dns_abort_query(s);
59155943
return;
59165944
}
59175945
ip = (buf[pos + 3] & 0xFF) |
@@ -5920,16 +5948,14 @@ void dns_callback(int dns_sd, uint16_t ev, void *arg)
59205948
((buf[pos + 0] & 0xFF) << 24);
59215949
if (s->dns_lookup_cb)
59225950
s->dns_lookup_cb(ip);
5923-
s->dns_id = 0;
5924-
s->dns_query_type = DNS_QUERY_TYPE_NONE;
5951+
dns_abort_query(s);
59255952
return;
59265953
} else if (s->dns_query_type == DNS_QUERY_TYPE_PTR && ee16(rr->type) == DNS_PTR) {
59275954
if (dns_copy_name((const uint8_t *)buf, dns_len, pos,
59285955
s->dns_ptr_name, sizeof(s->dns_ptr_name)) == 0) {
59295956
if (s->dns_ptr_cb)
59305957
s->dns_ptr_cb(s->dns_ptr_name);
5931-
s->dns_id = 0;
5932-
s->dns_query_type = DNS_QUERY_TYPE_NONE;
5958+
dns_abort_query(s);
59335959
return;
59345960
}
59355961
}

0 commit comments

Comments
 (0)