@@ -4264,5 +4264,57 @@ START_TEST(test_regression_dhcp_nak_restarts_configuration)
42644264}
42654265END_TEST
42664266
4267+ /* DNS response parser does not check the RCODE field. An error response
4268+ * such as NXDOMAIN (RCODE=3) passes the QR+RD check, the empty answer
4269+ * section is silently skipped, and the query stays active until the
4270+ * retry timer fires. RFC 1035 s4.1.1: RCODE != 0 is an error. */
4271+ START_TEST (test_regression_dns_rcode_error_aborts_query )
4272+ {
4273+ struct wolfIP s ;
4274+ struct tsocket * ts ;
4275+ uint8_t response [64 ];
4276+ struct dns_header * hdr = (struct dns_header * )response ;
4277+ struct dns_question * q ;
4278+ int pos ;
4279+
4280+ wolfIP_init (& s );
4281+ mock_link_init (& s );
4282+ s .dns_server = 0x08080808U ;
4283+
4284+ /* Set up an active DNS query */
4285+ s .dns_udp_sd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_DGRAM , WI_IPPROTO_UDP );
4286+ ck_assert_int_gt (s .dns_udp_sd , 0 );
4287+ ts = & s .udpsockets [SOCKET_UNMARK (s .dns_udp_sd )];
4288+ s .dns_id = 0xABCD ;
4289+ s .dns_query_type = DNS_QUERY_TYPE_A ;
4290+ s .dns_lookup_cb = test_dns_lookup_cb ;
4291+
4292+ /* Build a DNS response with RCODE=3 (NXDOMAIN).
4293+ * flags = 0x8183: QR=1, RD=1, RA=1, RCODE=3
4294+ * ancount=0 (no answers, as expected for NXDOMAIN). */
4295+ memset (response , 0 , sizeof (response ));
4296+ hdr -> id = ee16 (0xABCD );
4297+ hdr -> flags = ee16 (0x8183 );
4298+ hdr -> qdcount = ee16 (1 );
4299+ hdr -> ancount = ee16 (0 );
4300+ pos = sizeof (struct dns_header );
4301+ response [pos ++ ] = 3 ; memcpy (& response [pos ], "foo" , 3 ); pos += 3 ;
4302+ response [pos ++ ] = 3 ; memcpy (& response [pos ], "com" , 3 ); pos += 3 ;
4303+ response [pos ++ ] = 0 ;
4304+ q = (struct dns_question * )(response + pos );
4305+ q -> qtype = ee16 (DNS_A );
4306+ q -> qclass = ee16 (1 );
4307+ pos += sizeof (struct dns_question );
4308+
4309+ enqueue_udp_rx (ts , response , (uint16_t )pos , DNS_PORT );
4310+ dns_callback (s .dns_udp_sd , CB_EVENT_READABLE , & s );
4311+
4312+ /* The query must be aborted after receiving an authoritative error,
4313+ * not left active for the retry timer to fire. */
4314+ ck_assert_uint_eq (s .dns_id , 0 );
4315+ ck_assert_int_eq (s .dns_query_type , DNS_QUERY_TYPE_NONE );
4316+ }
4317+ END_TEST
4318+
42674319
42684320/* ----------------------------------------------------------------------- */
0 commit comments