Skip to content

Commit 6af6ca5

Browse files
committed
feat(mdns): add check of instance when handling PTR query
1 parent 3f12ef6 commit 6af6ca5

File tree

1 file changed

+105
-5
lines changed

1 file changed

+105
-5
lines changed

components/mdns/mdns.c

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,21 +1871,44 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
18711871
packet->id = parsed_packet->id;
18721872

18731873
mdns_parsed_question_t *q = parsed_packet->questions;
1874+
uint32_t out_record_nums = 0;
18741875
while (q) {
18751876
shared = q->type == MDNS_TYPE_PTR || q->type == MDNS_TYPE_SDPTR || !parsed_packet->probe;
18761877
if (q->type == MDNS_TYPE_SRV || q->type == MDNS_TYPE_TXT) {
18771878
mdns_srv_item_t *service = _mdns_get_service_item_instance(q->host, q->service, q->proto, NULL);
18781879
if (service == NULL || !_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
18791880
_mdns_free_tx_packet(packet);
18801881
return;
1882+
} else {
1883+
out_record_nums++;
18811884
}
18821885
} else if (q->service && q->proto) {
18831886
mdns_srv_item_t *service = _mdns_server->services;
18841887
while (service) {
18851888
if (_mdns_service_match_ptr_question(service->service, q)) {
1886-
if (!_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
1887-
_mdns_free_tx_packet(packet);
1888-
return;
1889+
mdns_parsed_record_t *r = parsed_packet->records;
1890+
bool is_record_exist = false;
1891+
while (r) {
1892+
if (service->service->instance && r->host) {
1893+
if (_mdns_service_match_instance(service->service, r->host, r->service, r->proto, NULL) && r->ttl > (MDNS_ANSWER_PTR_TTL / 2)) {
1894+
is_record_exist = true;
1895+
break;
1896+
}
1897+
} else if (!service->service->instance && !r->host) {
1898+
if (_mdns_service_match(service->service, r->service, r->proto, NULL) && r->ttl > (MDNS_ANSWER_PTR_TTL / 2)) {
1899+
is_record_exist = true;
1900+
break;
1901+
}
1902+
}
1903+
r = r->next;
1904+
}
1905+
if (!is_record_exist) {
1906+
if (!_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
1907+
_mdns_free_tx_packet(packet);
1908+
return;
1909+
} else {
1910+
out_record_nums++;
1911+
}
18891912
}
18901913
}
18911914
service = service->next;
@@ -1894,22 +1917,31 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
18941917
if (!_mdns_create_answer_from_hostname(packet, q->host, send_flush)) {
18951918
_mdns_free_tx_packet(packet);
18961919
return;
1920+
} else {
1921+
out_record_nums++;
18971922
}
18981923
} else if (q->type == MDNS_TYPE_ANY) {
18991924
if (!_mdns_append_host_list(&packet->answers, send_flush, false)) {
19001925
_mdns_free_tx_packet(packet);
19011926
return;
1927+
} else {
1928+
out_record_nums++;
19021929
}
19031930
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
19041931
} else if (q->type == MDNS_TYPE_PTR) {
19051932
mdns_host_item_t *host = mdns_get_host_item(q->host);
19061933
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) {
1934+
_mdns_free_tx_packet(packet);
19071935
return;
1936+
} else {
1937+
out_record_nums++;
19081938
}
19091939
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
19101940
} else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, NULL, send_flush, false)) {
19111941
_mdns_free_tx_packet(packet);
19121942
return;
1943+
} else {
1944+
out_record_nums++;
19131945
}
19141946

19151947
if (parsed_packet->src_port != MDNS_SERVICE_PORT && // Repeat the queries only for "One-Shot mDNS queries"
@@ -1943,6 +1975,10 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
19431975
}
19441976
q = q->next;
19451977
}
1978+
if (out_record_nums == 0) {
1979+
_mdns_free_tx_packet(packet);
1980+
return;
1981+
}
19461982
if (unicast || !send_flush) {
19471983
memcpy(&packet->dst, &parsed_packet->src, sizeof(esp_ip_addr_t));
19481984
packet->port = parsed_packet->src_port;
@@ -3336,7 +3372,11 @@ static bool _mdns_question_matches(mdns_parsed_question_t *question, uint16_t ty
33363372
&& !strcasecmp(service->service->service, question->service)
33373373
&& !strcasecmp(service->service->proto, question->proto)
33383374
&& !strcasecmp(MDNS_DEFAULT_DOMAIN, question->domain)) {
3339-
return true;
3375+
if (!service->service->instance) {
3376+
return true;
3377+
} else if (service->service->instance && question->host && !strcasecmp(service->service->instance, question->host)) {
3378+
return true;
3379+
}
33403380
}
33413381
} else if (service && (type == MDNS_TYPE_SRV || type == MDNS_TYPE_TXT)) {
33423382
const char *name = _mdns_get_service_instance_name(service->service);
@@ -3635,6 +3675,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
36353675
parsed_packet->id = header.id;
36363676
esp_netif_ip_addr_copy(&parsed_packet->src, &packet->src);
36373677
parsed_packet->src_port = packet->src_port;
3678+
parsed_packet->records = NULL;
36383679

36393680
if (header.questions) {
36403681
uint8_t qs = header.questions;
@@ -3821,7 +3862,12 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
38213862
_mdns_search_result_add_ptr(search_result, name->host, name->service, name->proto,
38223863
packet->tcpip_if, packet->ip_protocol, ttl);
38233864
} else if ((discovery || ours) && !name->sub && _mdns_name_is_ours(name)) {
3824-
if (discovery && (service = _mdns_get_service_item(name->service, name->proto, NULL))) {
3865+
if (name->host[0]) {
3866+
service = _mdns_get_service_item_instance(name->host, name->service, name->proto, NULL);
3867+
} else {
3868+
service = _mdns_get_service_item(name->service, name->proto, NULL);
3869+
}
3870+
if (discovery && service) {
38253871
_mdns_remove_parsed_question(parsed_packet, MDNS_TYPE_SDPTR, service);
38263872
} else if (service && parsed_packet->questions && !parsed_packet->probe) {
38273873
_mdns_remove_parsed_question(parsed_packet, type, service);
@@ -3831,6 +3877,45 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
38313877
_mdns_remove_scheduled_answer(packet->tcpip_if, packet->ip_protocol, type, service);
38323878
}
38333879
}
3880+
if (service) {
3881+
mdns_parsed_record_t *record = malloc(sizeof(mdns_parsed_record_t));
3882+
if (!record) {
3883+
HOOK_MALLOC_FAILED;
3884+
goto clear_rx_packet;
3885+
}
3886+
record->next = parsed_packet->records;
3887+
parsed_packet->records = record;
3888+
record->type = MDNS_TYPE_PTR;
3889+
record->record_type = MDNS_ANSWER;
3890+
record->ttl = ttl;
3891+
record->host = NULL;
3892+
record->service = NULL;
3893+
record->proto = NULL;
3894+
if (name->host[0]) {
3895+
record->host = malloc(MDNS_NAME_BUF_LEN);
3896+
if (!record->host) {
3897+
HOOK_MALLOC_FAILED;
3898+
goto clear_rx_packet;
3899+
}
3900+
memcpy(record->host, name->host, MDNS_NAME_BUF_LEN);
3901+
}
3902+
if (name->service[0]) {
3903+
record->service = malloc(MDNS_NAME_BUF_LEN);
3904+
if (!record->service) {
3905+
HOOK_MALLOC_FAILED;
3906+
goto clear_rx_packet;
3907+
}
3908+
memcpy(record->service, name->service, MDNS_NAME_BUF_LEN);
3909+
}
3910+
if (name->proto[0]) {
3911+
record->proto = malloc(MDNS_NAME_BUF_LEN);
3912+
if (!record->proto) {
3913+
HOOK_MALLOC_FAILED;
3914+
goto clear_rx_packet;
3915+
}
3916+
memcpy(record->proto, name->proto, MDNS_NAME_BUF_LEN);
3917+
}
3918+
}
38343919
}
38353920
} else if (type == MDNS_TYPE_SRV) {
38363921
mdns_result_t *result = NULL;
@@ -4161,6 +4246,21 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
41614246
}
41624247
free(question);
41634248
}
4249+
while (parsed_packet->records) {
4250+
mdns_parsed_record_t *record = parsed_packet->records;
4251+
parsed_packet->records = parsed_packet->records->next;
4252+
if (record->host) {
4253+
free(record->host);
4254+
}
4255+
if (record->service) {
4256+
free(record->service);
4257+
}
4258+
if (record->proto) {
4259+
free(record->proto);
4260+
}
4261+
record->next = NULL;
4262+
free(record);
4263+
}
41644264
free(parsed_packet);
41654265
if (browse_result_instance) {
41664266
free(browse_result_instance);

0 commit comments

Comments
 (0)