Skip to content

Commit 37eaa64

Browse files
committed
Do not send ttl_exceeded on locally-destined TCP packets
F/697
1 parent 4502d00 commit 37eaa64

2 files changed

Lines changed: 46 additions & 22 deletions

File tree

src/test/unit/unit.c

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8041,11 +8041,14 @@ START_TEST(test_dns_abort_query_null_noop)
80418041
}
80428042
END_TEST
80438043

8044-
START_TEST(test_tcp_input_ttl_zero_sends_icmp)
8044+
START_TEST(test_tcp_input_ttl_zero_local_ack_still_processes)
80458045
{
80468046
struct wolfIP s;
80478047
struct tsocket *ts;
8048-
struct wolfIP_tcp_seg seg;
8048+
struct tcp_seg_buf segbuf;
8049+
struct wolfIP_tcp_seg *queued;
8050+
struct wolfIP_tcp_seg ackseg;
8051+
struct pkt_desc *desc;
80498052

80508053
wolfIP_init(&s);
80518054
mock_link_init(&s);
@@ -8061,20 +8064,43 @@ START_TEST(test_tcp_input_ttl_zero_sends_icmp)
80618064
ts->dst_port = 5678;
80628065
ts->local_ip = 0x0A000001U;
80638066
ts->remote_ip = 0x0A000002U;
8067+
ts->sock.tcp.snd_una = 100;
8068+
ts->sock.tcp.seq = 101;
8069+
ts->sock.tcp.bytes_in_flight = 1;
8070+
fifo_init(&ts->sock.tcp.txbuf, ts->txmem, TXBUF_SIZE);
80648071

8065-
memset(&seg, 0, sizeof(seg));
8066-
seg.ip.ver_ihl = 0x45;
8067-
seg.ip.ttl = 0;
8068-
seg.ip.proto = WI_IPPROTO_TCP;
8069-
seg.ip.len = ee16(IP_HEADER_LEN + TCP_HEADER_LEN);
8070-
seg.ip.src = ee32(ts->remote_ip);
8071-
seg.ip.dst = ee32(ts->local_ip);
8072-
seg.dst_port = ee16(ts->src_port);
8073-
seg.src_port = ee16(ts->dst_port);
8074-
seg.hlen = TCP_HEADER_LEN << 2;
8075-
fix_tcp_checksums(&seg);
8076-
tcp_input(&s, TEST_PRIMARY_IF, &seg, (uint32_t)(ETH_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN));
8077-
ck_assert_uint_gt(last_frame_sent_size, 0);
8072+
memset(&segbuf, 0, sizeof(segbuf));
8073+
queued = &segbuf.seg;
8074+
queued->ip.len = ee16(IP_HEADER_LEN + TCP_HEADER_LEN + 1);
8075+
queued->hlen = TCP_HEADER_LEN << 2;
8076+
queued->seq = ee32(100);
8077+
ck_assert_int_eq(fifo_push(&ts->sock.tcp.txbuf, &segbuf, sizeof(segbuf)), 0);
8078+
desc = fifo_peek(&ts->sock.tcp.txbuf);
8079+
ck_assert_ptr_nonnull(desc);
8080+
desc->flags |= PKT_FLAG_SENT;
8081+
8082+
memset(&ackseg, 0, sizeof(ackseg));
8083+
ackseg.ip.ver_ihl = 0x45;
8084+
ackseg.ip.ttl = 0;
8085+
ackseg.ip.proto = WI_IPPROTO_TCP;
8086+
ackseg.ip.len = ee16(IP_HEADER_LEN + TCP_HEADER_LEN);
8087+
ackseg.ip.src = ee32(ts->remote_ip);
8088+
ackseg.ip.dst = ee32(ts->local_ip);
8089+
ackseg.src_port = ee16(ts->dst_port);
8090+
ackseg.dst_port = ee16(ts->src_port);
8091+
ackseg.hlen = TCP_HEADER_LEN << 2;
8092+
ackseg.flags = TCP_FLAG_ACK;
8093+
ackseg.ack = ee32(101);
8094+
ackseg.win = ee16(32);
8095+
fix_tcp_checksums(&ackseg);
8096+
8097+
tcp_input(&s, TEST_PRIMARY_IF, &ackseg,
8098+
(uint32_t)(ETH_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN));
8099+
8100+
ck_assert_uint_eq(last_frame_sent_size, 0U);
8101+
ck_assert_uint_eq(ts->sock.tcp.snd_una, 101U);
8102+
ck_assert_uint_eq(ts->sock.tcp.bytes_in_flight, 0U);
8103+
ck_assert_ptr_eq(fifo_peek(&ts->sock.tcp.txbuf), NULL);
80788104
}
80798105
END_TEST
80808106

@@ -19246,7 +19272,7 @@ Suite *wolf_suite(void)
1924619272
tcase_add_test(tc_utils, test_dns_callback_wrong_id_ignored);
1924719273
tcase_add_test(tc_utils, test_dns_callback_abort_clears_query_state);
1924819274
tcase_add_test(tc_utils, test_dns_abort_query_null_noop);
19249-
tcase_add_test(tc_utils, test_tcp_input_ttl_zero_sends_icmp);
19275+
tcase_add_test(tc_utils, test_tcp_input_ttl_zero_local_ack_still_processes);
1925019276
tcase_add_test(tc_utils, test_dns_callback_bad_rr_rdlen);
1925119277
tcase_add_test(tc_utils, test_dhcp_parse_offer_no_match);
1925219278
tcase_add_test(tc_utils, test_dhcp_parse_ack_invalid);

src/wolfip.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3313,6 +3313,7 @@ static void tcp_input(struct wolfIP *S, unsigned int if_idx,
33133313
struct wolfIP_tcp_seg *tcp, uint32_t frame_len)
33143314
{
33153315
int i;
3316+
int matched = 0;
33163317

33173318
/* validate minimum TCP segment length */
33183319
if (frame_len < sizeof(struct wolfIP_tcp_seg))
@@ -3363,11 +3364,7 @@ static void tcp_input(struct wolfIP *S, unsigned int if_idx,
33633364
continue;
33643365
}
33653366
}
3366-
/* Check IP ttl */
3367-
if (tcp->ip.ttl == 0) {
3368-
wolfIP_send_ttl_exceeded(S, if_idx, &tcp->ip);
3369-
return;
3370-
}
3367+
matched = 1;
33713368
/* Validate minimum TCP header length (data offset). */
33723369
if ((tcp->hlen >> 2) < TCP_HEADER_LEN) {
33733370
return; /* malformed: TCP header below minimum length */
@@ -3605,7 +3602,8 @@ static void tcp_input(struct wolfIP *S, unsigned int if_idx,
36053602
}
36063603
}
36073604
}
3608-
tcp_send_reset_reply(S, if_idx, tcp);
3605+
if (!matched)
3606+
tcp_send_reset_reply(S, if_idx, tcp);
36093607
}
36103608

36113609
static void tcp_rto_cb(void *arg)

0 commit comments

Comments
 (0)